Flexbox items go out of the browser window - html

I've come across a problem while building a website; it is that some items go out of the screen.
Following is a simple code that demonstrate the problem. Here, the div with an id of name-h is the element that disappears:
html, body {
width: 100%;
height: 100%;
}
#container {
display: flex;
flex-direction: column;
justify-content: center;
align-content: center;
height: 100%;
}
#name-h {
font-size: 34px;
margin-bottom: 450px;
}
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
</head>
<body>
<div id="container">
<div id="name-h">
<p id="first-name">FirstNmae</p>
<p id="last-name">LastName</p>
</div>
<div id="links">
<p class="link">Resume</p>
<p class="link">Portfolio</p>
<p class="link">Blog</p>
</div>
</div>
</body>
What is the cause of this problem?
How can I fix it?
Edit 1
It turned out that I had provided some false conclusions in the original question, so I edited the question to remove them.-
Edit 2 (Important Clarification)
What I know is that html increases in height in order to contain its elements, and when its height becomes greater than the screen, scrollbars appear, right? Why doesn't this happen in my case? Why even I am assigning height: 100% to html, body, and #container?-
Edit 3 (Is flexbox the reason?)
strong textI think that the flexbox might be the cause of the problem: If only we remove display: flex; from the code above, every thing works as expected. I am thinking that the flexbox might be behaving like an absolutely positioned element, which causes its items to go out of the screen. What do you think?-
Edit 4
Here is a demonstration for the case with dummy text: link. Note that the actual text starts with "Lorem ipsum dolor sit amet, consectetuer adipiscing elit", while the text displayed starts with something else due to the problem.-
Edit 5
I am using html, body { height: 100%; width: 100%} and #container {height: 100%;} in order to center the contents of the flex relative to the whole viewport, not only to the flex itself.

You have declared the height of container which is also a flexbox here height:100%; and given a margin-bottom:450px; to your inner div #name-h
This is possibly causing the issue. Try changing the height of container with height:auto;
Hope this help.

You don't need to specify height: 100%; in html or body. The width is by default 100% and the height varies according to the content inside.
You can solve your issue by removing html, body { height: 100%; width: 100%} and more specifically html{ height: 100%;}.
You shouldn't style html viewport dimensions using css since it could break your code. It is good practice to style your div tags and not your html tag.
Here is the link.

I would try setting flex-flow: column wrap; in container. Either this give the container a width. I love flex-box but sometimes as with any relationship it will occasionally drive you crazy

Adding a wrapper div around the #container div prevents items from going out of the browser window. However, #container items are not still centered relative to the viewport.
Here is the modified code:
html,
body {
width: 100%;
height: 100%;
}
#container {
display: flex;
flex-direction: column;
justify-content: center;
align-content: center;
height: 100%;
}
#name-h {
font-size: 34px;
margin-bottom: 450px;
}
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
</head>
<body>
<div> <!--The only new div-->
<div id="container">
<div id="name-h">
<p id="first-name">FirstNmae</p>
<p id="last-name">LastName</p>
</div>
<div id="links">
<p class="link">Resume</p>
<p class="link">Portfolio</p>
<p class="link">Blog</p>
</div>
</div>
</div>
</body>

Flex-wrap property can solve this issue. Use it like this:
flex-wrap: wrap

Related

How to make image nested in div fill the remaining space on the page?

I'm learning CSS and got stuck creating a layout that contains a header and an image that fills the rest of the screen. Using the following code, I'm able to achieve what I'm looking for:
html, body {
height: 100%;
margin: 0;
}
.container {
display: flex;
flex-direction: column;
height: 100%;
}
.image-container {
flex: 1;
}
img {
width: 100%;
height: 100%;
object-fit: contain;
}
<html>
<body>
<div class="container">
<div class="header">
<h1>Test Page</h1>
</div>
<!-- <div class="image-container"> -->
<img src="https://picsum.photos/500/300"/>
<!-- </div> -->
</div>
</body>
</html>
Now the problem is that I want to wrap the image element into a div as I'd like to position an overlay on top of the image. As soon as I nest the img within a div, the resizing doesn't work properly anymore. If the screen is wide, the image overflows to the bottom, creating a vertical scrollbar.
I've tried a lot of things, but nothing's worked so far. Can you explain to me why introducing the div (image-container) changes the layout and how to make it behave like the version without the div? That'd be great, thanks in advance!
EDIT:
I want the image to be displayed exactly like in the snippet I posted. It should be as large as possible, but only so large that the whole image is still visible and nothing is cropped. For a wide window, there should be blank bars left and right of the image. For a narrow but tall window, there should be blank bars above/beyond the image.
My issue is that as soon as I add the <div class="image-container">, the image always takes the whole width. For a wide window, I get scrollbars and can't see the whole image anymore. I'd like to know how I can get the image to scale like in the version without the additional <div>. I'd also like to understand why adding the <div> changes how the image is scaled.
EDIT 2:
Someone suggested to add overflow: hidden; on .image-container, but deleted their answer. This does in fact work (overflow: hidden/scroll/auto; work, overflow: visible; does not), but now I'm completely confused to why that's the case. I thought that overflow would control if overflow is visible, but wouldn't affect the size of the content being displayed. In this case though, it seems like the overflow property does have an effect on the size of the picture being displayed. That's weird and if anyone knows what's going on, please let me know!
Flex is already helping the image take up as much space as possible, so the height: 100% and width: 100% were causing the image to grow.
For getting something to appear on top of the image, I would recommend looking into position: absolute or position: relative
html,
body {
height: 100%;
margin: 0;
}
.container {
display: flex;
flex-direction: column;
height: 100%;
}
.image-container {
display: flex;
justify-content: center;
}
img {
object-fit: contain;
}
<html>
<body>
<div class="container">
<div class="header">
<h1>Test Page</h1>
</div>
<div class="image-container">
<img src="https://picsum.photos/500/300" />
</div>
</div>
</body>
</html>

Why the `position: absolute` children not honour their relative parent?

I want to make a card which contains an image and some texts. The text should be put over the image. So I put all of them in a .container which has position: relative with themselves set to position: absolute.
For the text:
the 1st part of the text sits at the left side with the wrapper .row-start, one by one in a row
the 2nd part of the text sits at the right side with the wrapper .row-end
of course both within the container
Html:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<div class="container">
<img src="https://upload.wikimedia.org/wikipedia/commons/e/e4/Color-blue.JPG"/>
<div class="row-start">
<p>Attr 1</p>
<p>Attr 2</p>
</div>
<div class="row-end">
<p>Attr 3</p>
</div>
</div>
</body>
</html>
Css:
.container {
position: relative;
height: 15em;
}
.container img {
width: auto;
height: 100%;
}
.row-start {
position: absolute;
left: 1em;
display: flex;
flex-direction: row;
}
.row-end {
position: absolute;
right: 1em;
}
What's the problem
What confuse me is that it seems .row-start can work while .row-end doesn't honor its .container parent at all. And it will be placed outside the .container div and from the right side of the page (so it honors the
<html> tag?)
What am I missing or doing something wrong here?
And any best practice for doing this? Thanks
Your container element is a block, so it's size it's the size of the screen. I have added a background: red to your container so I can show you what i mean
You can see it on this pluckr:
https://plnkr.co/edit/QdsaqIU5X7xYX4UXksT9?p=preview
.container {
position: relative;
background: red;
}
Your .container DIV doesn't have a width definition, so it's 100% wide, i.e. full width (of its parent / in this example of the window). The height is 15 em, which apparently is more than the height of the image.
So your absolute DIVs are positioned in relation to the .container, but that container is larger than you apparently think it is - the image only covers part of the container div.
To change that, you can define a width for the container, and 100% width or the image.

Height: 100% Not Working Even Though All Parents Have Height: 100%

Setting height: 100% for <div> .ui in the HTML below does not work even though all the parent elements have height set to 100%.
Could this be because I'm using <core-header-panel>? I checked its code but I don't see anything that would override the height.
Could this be due to using the layout horizontal attributes?
The layout attributes (built on top of CSS Flexbox) and core-header-panel are part of Polymer.
This is the HTML (simplified):
<!doctype html>
<html>
<body unresolved>
<core-header-panel>
<div layout horizontal class="container">
<div class="ui"> </div> <!-- this does not take up 100% of
the height -->
<div flex class="items"> </div> <!-- this has content inside it which fills
the height, but the <div> itself doesn't -->
And this is my CSS (simplified):
html, body {
height: 100%;
}
core-header-panel {
height: 100%;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
.container {
width: 100%;
height: 100%;
}
.ui {
height: 100%;
position: relative;
margin: 30px;
}
.items {
display: inline-block;
height: 100%;
margin: 30px;
}
Any help would be appreciated.
EDIT 1: Using DevTools I noticed that <core-header-panel> does take up 100% of the height, but <div> .container does not. height: 100%; is not crossed out for .container in the "Styles" tab in DevTools.
EDIT 2: INFO ON POLYMER Here is a link to a simple explanation of Polymer layout attributes and here is a link to some information on core header panel. There are Github links on the top right of both pages.
The solution was actually really simple.
I had to add fullbleed vertical layout to <core-header-panel>. fullbleed forces it to take up the entire height of the parent. I didn't see a reason for this since I specified height: 100%, but it appears that it does not work without it.
I also added fit to <div> .container to make it fit the parent.
<!doctype html>
<html>
<body unresolved>
<core-header-panel fullbleed vertical layout> <!-- added "fullbleed vertical layout" here -->
<div fit layout horizontal class="container"> <!-- added "fit" here -->
<div class="ui"> </div>
<div flex class="items"> </div>

Create fixed height horizontal div with a fluid one

I'm trying to establish a layout with in the base three rows: A header, content and footer div.
The two outer most div's are of a fixed height; The center div has to be fluid and adapt itself to the height of the browser screen.
Could someone point me in the right direction how to tackle this with proper CSS? For now I'm not yet interested in a javascript solution. As CSS doesn't provide a clean answer, a javascript solution comes eminent!
This is how far I came:
<div id='header'>Header</div>
<div id='content'>
<div id='innerContent'>
This is the fluid part
</div>
</div>
<div id='footer'>footer</div>
css:
#header {
position:absolute;
top:0px;
left:0px;
height:100px;
z-index:5;
}
#content {
position:absolute;
top:0px;
left:0px;
height:100%;
z-index:2;
}
#innerContent {
margin-top:100px;
height:100%;
}
#footer {
height:400px;
}
EDIT:
I'm sorry, I feel embarassed. I made something similar about a year ago, but at first I didn't think it was possible to adjust it to this situation. Apparently it was.
As I think other's have already said, it is possible to put the footer div at the bottom by positioning it absolutely. The problem is to adjust it's position when the content div gets larger. Since the footer is absolutely positioned it won't follow the content div's flow, which makes it stay at the same place even though the content expands.
The trick is to wrap everything in an absolutely positioned div. It will expand if it's content gets larger, and the footer div will be positioned according to the wrapper's borders instead of the document's borders.
Here's the code. Try to put a bunch of <br /> tags within the content div and you'll see that everything adjusts.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Layout test</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
#wrapper {
min-height: 100%;
min-width: 100%;
position: absolute;
}
#header {
height: 100px;
background-color: red;
}
#content {
background-color: gray;
margin-bottom: 50px;
}
#footer {
height: 400px;
min-width: 100%;
position: absolute;
bottom: 0px;
margin-bottom: -350px;
background-color: blue;
}
</style>
</head>
<body>
<div id="wrapper">
<div id='header'>Header</div>
<div id='content'>
Content
</div>
<div id='footer'>footer</div>
</div>
</body>
</html>
ORIGINAL:
Sadly, css lacks a clean way to do this. You don't know the viewport height (which you called h) and therefore can't calculate h-100-50 You have to build your website so that most people will see 50px of the footer div. The way to do that is to set a min-height for the content div.
The min-height value must be derived from some standard viewport height. Google Labs have published their data on viewport sizes for their visitors and made a great visualization of it here:
http://browsersize.googlelabs.com/
I design for my own viewport, which is 620px high (according to google ~80% have this viewport height). Therefore the min-height for the content div should be 620-100-50 = 470 px.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Layout test</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
#header {
height: 100px;
background-color: red;
}
#content {
min-height: 470px;
background-color: gray;
}
#footer {
height: 400px;
background-color: blue;
}
</style>
</head>
<body>
<div id='header'>Header</div>
<div id='content'>
Content
</div>
<div id='footer'>footer</div>
</body>
</html>
If I understand your problem correctly I think this might lead you into the right direction.
http://jsfiddle.net/mikevoermans/r6Saq/1/
I'll take a poke at it. Not sure if I read your screenshot correctly but I set the content div to be 50-100px in height.
Here is my jsfiddle: http://jsfiddle.net/AX5Bh/
I am using the min-height and max-height CSS attributes to control the #innerContent div.
If you horizontally expand the result window you will see that some of the text is highlighted . I have set the content to be hidden if it is larger than the #innerContent div. You might want something different. I only highlighted the text with an <em> tag to demonstrate that max-height was working.
If you remove all the text but the first sentence you will see it is 50px in height.
Here is a link to browser support of min-height and max-height: http://caniuse.com/#search=max-height

how to size a div's height to its container height, using CSS?

How to size a div's height to its container height, using CSS ?
<div class='container'><br>
<div style='display: block; height: 500px'>left</div><br>
<div id='to-be-sized' >right</div><br>
</div>
You can either:
use the incomplete but philosophically correct path of pure CSS and face every kind of incompatibility between browsers
or
write 3 lines of dirty semantically incorrect and devil made table and have it work perfectly everywhere
Your pick :)
There's a way to do this IF you happen to be using jQuery. As you asked for CSS this might not be an option available to you, but if you can utilise it it will do exactly what you want.
$(divToResize).css('height',$(container).innerHeight());
$(divToResize) is the selector for the DIV you wish to match the height of it's container and $(container) is logically the container whose height you want to get.
This will work regardless of if the container's height is specified in CSS or not.
I know this was answered forever ago, but when I run into this issue nowadays, I use Flex Box. It's awesome. See A Complete Guide to Flexbox by Chris Coyier
.parent {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
width: 100%;
}
.child {
flex-grow: 1;
}
.child1 {
min-height: 200px;
background-color: #fee;
}
.child2 {
background-color:#eef;
}
<div class="parent">
<div class="child child1">Child 1</div>
<div class="child child2">Child 2</div>
</div>
The Flexbox Layout (Flexible Box) module aims at providing a more efficient way to lay out, align and distribute space among items in a container, even when their size is unknown and/or dynamic (thus the word "flex").
The main idea behind the flex layout is to give the container the ability to alter its items' width/height (and order) to best fill the available space (mostly to accommodate to all kind of display devices and screen sizes). A flex container expands items to fill available free space, or shrinks them to prevent overflow.
Most importantly, the flexbox layout is direction-agnostic as opposed to the regular layouts (block which is vertically-based and inline which is horizontally-based). While those work well for pages, they lack flexibility (no pun intended) to support large or complex applications (especially when it comes to orientation changing, resizing, stretching, shrinking, etc.).
If my understanding is correct and the default height of a div where no height is specified is auto then this is not possible without setting an explicit height on the containing div. If an explicit height is set on the containing div then height:100% on the contained div will mean that it grows to the height of the container.
It seems like you are trying to get equal height columns. You could use the fauxcolumns method where a background image is used to fake the equal height. There are other methods out there.
You can tell the container div to display as table and have the inner div to display as a table cell.
The HTML
<body>
<div id="wrap">
<div id="header">
<h1>
My Header</h1>
</div>
<div id="main">
<ul id="nav">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<div id="primaryContent">
</div>
</div>
<div id="footer">
<h1>
My Footer</h1>
</div>
</div>
The CSS
#wrap
{
width: 800px;
margin: auto;
}
#header
{
background: red;
}
#main
{
display: table;
}
#nav
{
background: gray;
width: 150px;
display: table-cell;
}
#primaryContent
{
background: yellow;
padding: 0 .5em;
display: table-cell;
}
Fixes for IE
#wrap
{
width: 800px;
margin: auto;
}
#header, #footer
{
background: red;
}
#main
{
background: url(../bg.png) repeat-y;
}
#nav
{
background: gray;
width: 150px;
float: left;
}
#primaryContent
{
background: yellow;
margin-left: 150px;
padding: 0 .5em;
}
It's a tricky thing to do--there's no clear-cut best approach, but there are a few common ones.
If we assume that what you REALLY need is for the height of the right column to be (or appear to be) equivalent to the height of the left column, you can use any of the techniques frequently used to get equal height columns. This piece contains a few tricks to get the right look and behavior. I recommend reading it to see if it solves your problem.
The other approach uses Javascript to determine the height of the container, and setting your right-hand column to that. That technique has been discussed on SO here. As long as your container's size is not the only thing determining the size of your outer container, that should be a valid approach (if that's not the case, you'll have a chicken-egg problem that could cause weird behavior).
Sample code, you need to start from the html element so you can make use of the flexible height in the containers.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>100% Test</title>
<style type="text/css">
html, body, #inner { height: 100% }
#inner { border: 4px blue solid }
#container { height: 200px; border: 4px red solid }
</style>
</head>
<body>
<div id="container">
<div id="inner">
lorem ipsum
</div>
</div>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<style type="text/css">
.container{
position:relative;
background-color:#999;
}
#to-be-sized{
position:absolute;
top:0;
height:100%;
background-color:#ddd;
}
</style>
<body>
<div class='container'>
<br>
<div style='display: block; height: 500px'>left</div>
<br>
<div id='to-be-sized' >right</div><br>
</div>
</body>
</html>
CSS files use the 'padding' function to determine the height and depth of containers. To change the height of the container field simple insert of adjust the padding fields for the specified containers.
The code excerpt below is an example of the CSS used for a container class (you'd find this as in the html file.
.container{padding-top:100px;padding-bottom:50px}header
i use the overflow:hidden it work properly.
.bu {
overflow: hidden;
background-color:blue;
}
<div class="bu">
<button>english</button>
</div>
try adding this to the div to be resized
.layout-fill {
margin: 0;
width: 100%;
min-height: 100%;
height: 100%;
}
I did something similar to KyokoHunter:
$('div.row').each(function(){
var rowHeight = $(this).innerHeight();
$(this).children('div.column').css('height',rowHeight);
});
This goes through every row in a div "table" and makes the heights all match, as long as the divs are classed accordingly.