Div height 100% causing overflow issues - css

I recently decided to ditch tables and go with a div solution on this new project, however I'm having a really weird issue when setting a div within another div to 100% without it causing overflow equal to the height of the div's above it. It's acting like the browser isn't aware of the div's above it occupying that space.
I have a wrapper div with a fixed width and height set to 100%, within that is 3 column divs (left, mid and right) in the mid column I have 3 div's, the top 2 have fixed heights 90px and the 3rd is set to 100% to fill the rest of the content area but it's breaking out of the wrapper div and causing exactly 180px overflow. I setup this simple layout on JSFiddle: Height: 100% Div Issue
<body>
<div class="wrapper">
<div class="left">
<div style="background-color:fuchsia; height: 90px;"> </div>
</div>
<div class="mid">
<div style="background-color:purple; height: 90px; width: 998px;"> </div>
<div style="background-color:blue; height: 90px; width: 998px;"> </div>
<div style="background-color:black; height: 100%; width: 50%;"> </div>
</div>
<div class="right">
<div style="background-color:fuchsia; height: 90px;" class="right"> </div>
</div>
</div>
You will notice the black div is breaking out of the yellow (mid) div, this should not happen! Any help would be greatly appreciated. Thanks!

You're specifying a height of 100% on the black div, which ends up being relative to its parent (.mid) which also happens to contain the other elements that you gave 90px of height to. You have to account for those two siblings.
You can do this by using the calc() notation, though mobile browser support is bad and the function isn't supported in IE8 & below.
http://jsfiddle.net/KtUgF/5/
You can also use a negative top-margin on the black div equal to the sum of both of its siblings (180px):
http://jsfiddle.net/yrfnc/

This should fix the issue
height: 100vh;

Any reason why you can't just add overflow: hidden to the ".mid" div?
<div class="mid" style="overflow:hidden">
or
.mid {
float: left;
width: 998px;
height: 100%;
background-color: yellow;
overflow: hidden;
}

Related

Flex height not working in Chrome [duplicate]

This question already has answers here:
Chrome / Safari not filling 100% height of flex parent
(5 answers)
Closed 5 years ago.
To better see the issue run below html code on firefox and on chrome and see the difference.
The code works on all browsers but not Chrome. The issue is when you set display to flex and flex-direction to column, and set one of the flex items flex-grow to 1. The content of this flex item can't have have height set to 100%.
Can you help me with work around without using JavaScript, or css Calc function?
Because in the actual project things are much more complex than this.
h1 {
margin: 0;
padding: 0;
color: white;
}
div {
font-size: 38px;
color: white;
}
<body style="margin: 0; padding: 0;">
<div style="height: 100vh; background: royalblue;">
<div style="display: flex; flex-direction: column; height: 100%;">
<div style="background: rosybrown; flex-grow: 0;">
This is first flex item
</div>
<div style="flex-grow: 1; background-color: red;">
<div style="background-color: orange; height: 100%;">
This div is inside flex item that grows to fill the remaining space. and has css height 100% but its not filling its parent.
<br/>this div need to be filling its parent (the red div). this works on all other browsers.
</div>
</div>
</div>
</div>
</body>
Add height: 100% to the parent of the orange div:
<div style="flex-grow: 1; background-color: red; height: 100%;"><!-- ADJUSTMENT HERE -->
<div style="background-color: orange; height: 100%;">
This div is inside flex item that grows to fill the remaining space.
and has css height 100% but its not filling its parent.
<br/>this div need to be filling its parent (the red div).
this works on all other browsers.
</div>
</div>
Essentially, Chrome and Safari resolve percentage heights based on the value of the parent's height property. Firefox and IE11/Edge use the parent's computed flex height. For more details see bullet point #3 in this answer: https://stackoverflow.com/a/35051529/3597276

Equally distribute 3 divs within a div - without float

I have been reading widely about this but haven't been able to solve it to my satisfaction.
I have a div (<section>) that contains one <p> and 3 <div>s. I would like to distribute the 3 divs equally in one line so that the left border of the 1st div is on the left border of the document (<body>) and the the right border of the 3rd div on the right border of the document.
I don't want to use float because the backround-color would vanish.
I have tried flex but justify-content did not yield the expected outcome.
Here's the code on JSBIN.
Thank you!
You can use display: flex on the container, and set the width of the three div elements to take up one third (or as close as we can get) of its container. The container must have a set width (either pixel or percentage) for it to work.
#container {
display: flex;
height: 600px;
width: 600px;
background-color: lightgreen;
}
#container div {
border: 1px solid black;
margin: 0 10px;
width: 33.333333%;
}
#container div img {
width: 100%;
}
<div id="container">
<div id="content1">
I'm some content. Regardless of the width of this div, the content will move to the next line and stay within the div instead of overflowing.
<img src="http://i.imgur.com/P8z2H80.jpg">
</div>
<div id="content2">
I'm some more content. Regardless of the width of this div, the content will move to the next line and stay within the div instead of overflowing.
<img src="http://i.imgur.com/NfnBZAI.jpg">
</div>
<div id="content3">
I'm even more content. Regardless of the width of this div, the content will move to the next line and stay within the div instead of overflowing.
<img src="http://i.imgur.com/W8M37N2.jpg">
</div>
</div>

CSS Position element on bottom of container without removing it from flow

I have a container with 3 children elements.
<div class="container">
<img />
<div class="element1"></div>
<div class="element2 bottom"></div>
</div>
They must be positioned as shown on the diagram below:
image is in the top of the left column and nothing goes below it (it is the only element in the left column)
element1 is in the top of the right column
element2 is stick to the bottom of the right column (and must not collide with the element1 which is above it)
Does somebody know how to achieve such layout using pure CSS? Ideally I wouldn't like to add any markup, but I can do that if that's the only possible way.
The biggest problem I'm facing here is how to stick that second element (non-image) to the bottom of the container without removing it from the flow. Because if I use position: absolute and remove it from the flow, the elment above it can collide with it (both elements have unknown height).
Here's a pen to work on: http://codepen.io/anon/pen/yNwGvQ
I would suggest you to use two columns in your html and then use the property display: flex; for your right column as suggested in the article A Complete Guide to Flexbox.
http://codepen.io/AlexisBertin/pen/QboYyY
All the HTML:
<div class="container">
<div class="column column-left">
<div class="image">This is an image</div>
</div>
<div class="column column-right">
<div class="element1">This container has dynamic content so it's height is unknown and may change.<br/><br/> Some random content to make it larger. Some random content to make it larger. Some random content to make it larger. Some random content to make it larger. Some random content to make it larger.</div>
<div class="element2">This container also has dynamic content so it's height is unknown and may change</div>
</div>
</div>
Part of this CSS:
.column {
float: left;
height: 100%;
}
.column.column-left { width: 100px; }
.column.column-right {
width: calc(100% - 100px);
display: flex;
flex-direction: column;
justify-content: space-between;
}
Hope you get the idea. Good Luck'.
EDIT:
The easiest way to achieve this without declaring height to the container seems to only create a third parent div to the first block of the second column and define it as flex: 1; while the second block of this same second column would be define as flex: 0;.
http://codepen.io/anon/pen/yNwZmJ
More details explained in the comments.
The easiest solution I figured out is this one:
First you create this CSS:
.container {
width: 400px;
padding: 10px;
border: 1px solid red;
background-color: white;
}
.container > img {
float: left;
}
.container > div {
position: relative;
overflow: auto;
padding-left: 5px;
min-height: 120px;
}
.container > div > .bottom{
position: absolute;
bottom: 0;
display: block;
}
And then use these divs, depending on your content. The first one you use when you know your text is short:
<div class="container">
<img src="http://placehold.it/120x120">
<div>
<div>
<p>This container has dynamic content so it's height is unknown and may change.</p>
</div>
<div class="bottom">
<p>This container also has dynamic content so it's height is unknown and may change</div>
</div>
</div>
The second one you use when you know your text is long
<div class="container">
<img src="http://placehold.it/120x120">
<div>
<div>
<p>This container has dynamic content so it's height is unknown and may change.</p>
<p>Some random content to make it larger. Some random content to make it larger. Some random content to make it larger. Some random content to make it larger. Some random content to make it larger.</p>
</div>
<div>
<p>This container also has dynamic content so it's height is unknown and may change</p>
</div>
</div>
</div>
The difference is that you remove bottom class from the last div in your div that has long text.
Also in your CSS you can see .container > div{... min-height: 120px; ...}, you should set it to height of your image. In case you want the bottom text more down then you have to increase min-height to be bigger than your image height.
Here is it in action: http://codepen.io/anon/pen/YXgBXx

Div spacing problem

I am trying to space out DIVs. I have five DIVs that are 30px wide and want to put these into another DIV that is 150px wide. Sounds simple but I find the five DIVs don't fit.
5*30 = 150 (but it requires a 166px outer div for them to fit inline)
I have this fiddle
<div class="A">
<div class="B" >a</div>
<div class="B" >b</div>
<div class="B" >c</div>
<div class="B" >d</div>
<div class="B" >e</div>
<div class="B" >f</div>
</div>
div.A { background-color: Red; width: 150px;}
div.B { display: inline-block; height: 20px; width: 30px;}
Is there something I am missing? I can't understand why the browsers space the way they do.
As you are turning the divs into inline elements, the other inline content will also come into play, i.e. the white space between the elements. You get a space between each div, which takes up a few pixels more.
If you remove the white space between the divs, there will be no spaces between them, and five elements fit in 150 pixels:
http://jsfiddle.net/SLq6z/1/
Can you replace display:inline-block with float:left without causing any other issues? it solves your current problem...
div.B { float:left; height: 20px; width: 30px;}
Use float:left property for both your classes A and B ;).

2 divs (filling entire page)

I have one horizontally div on the top of my page with a height of 50px.
And now I want to put another div right below it which will fill the rest of entire page (should work with any kind of resolution).
Does anyone know how to do this only with CSS?
I'd appreciate any help. Thanks!
Although this is not stacking the div's it is very simple solution. Make a div that is 100% height and then place a div inside that is 50px in height.
<body style="height: 100%; width: 100%;">
<div style="height: 100%; width: 100%;">
<div style="height: 50px; width: 100%;">Header</div>
<!--Rest of Content-->
</div>
</body>
There are ways to do this. Here is an example using absolute positioning and a wrapper. Obviously ignore the colors-- they're just there so you can see what's going on.
<body style="margin: 0;height: 100%; background-color: yellow;">
<div style="background-color: green; height: 50px">top stuff</div>
<div style="position: absolute; top: 50px; bottom: 0; left:0; right: 0; background-color: blue">main stuff</div>
</body>
This is an example of a layout that is somewhat problematic with "pure" CSS but trivial with tables.
Firstly there is no way of expressing (ignoring CSS expressions, which you tend to want to avoid) "rest of the page" or "100% minus 50px" so the general solution to this problem is.
Create a container that is 100% height;
Put the header at height 50px;
The content simply takes up the rest of the space. Any styling is applied to the container not the content.
So:
<div id="container">
<div id="header"></div>
<div id="content"></div>
</div>
with:
html, body. #container { height: 100%; }
#container { height: 100%; min-height: 100%; }
#header { height: 50px; }
It gets trickier if you want a footer. That is typically positioned absolutely at the bottom and padding is used on the container so nothing appears under it.

Resources