Flexbox child with "overflow: hidden" overflowing grandparent margins - html

I'm trying to nest two child elements in a wrapper which specifies side margins so there's space between its contents and the sides of the screen when the display is narrow and a max-width for when the display is wide.
The second child has some overflow which should be visible while the first child should stay strictly within the wrapper's content box. With the first child removed, the second child behaves as desired. When I add in the first child though, it seems to completely ignore the wrapper's margins, stretching the wrapper's content box and breaking the second child along with it.
Applying overflow: hidden to the wrapper fixes the margin problem but clips the second child. Applying the margins to the first child didn't make it collapse with the parent since it's in a new block formatting context.
The only workaround I've found so far would be to do:
.wrapper {
> * {
margin-left: 1.5rem;
margin-right: 1.5rem;
}
}
and increase the max-width of the wrapper by 3rem but I was hoping there was some solution that didn't require me to shift the margin from the wrapper to its children.
https://codepen.io/HybridCore/pen/jjoWmd
body {
background-color: #000;
color: #FFF;
display: flex;
justify-content: center;
}
.wrapper {
margin: 0 1.5rem;
max-width: 40rem;
width: 100%;
}
.fit_content_box {
display: flex;
align-items: center;
}
.L {
min-width: 0;
flex: 1 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.R {
margin-left: 1rem;
height: 1rem;
width: 1rem;
background-color: #FFF;
}
.overflow {
display: flex;
justify-content: space-between;
}
.overflow>div {
width: 0;
display: flex;
justify-content: center;
}
<body>
<div class="wrapper">
<div class="fit_content_box">
<p class="L">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div class="R"></div>
</div>
<div class="overflow">
<div>
<p>0</p>
</div>
<div>
<p>12</p>
</div>
<div>
<p>24</p>
</div>
</div>
</div>
</body>

You mainly have two issues:
You are setting width:100% to the wrapper and this doesn't account for margin so you will logically have overflow and since the body is a flex container with justify-content:center the margin will overflow equally from both sides that's why you think it's not applied.
You are facing the min-width constraint of flexbox which is forcing you to set width:100% thinking it's the good solution. This same constraint is also preventing the element from shrinking lower than the 100% you specified (related: Why is a flex item limited to parent size?)
To fix this you need to remove width:100% from wrapper and consider min-width:0 instead. You can also remove the min-width applied to .L and you need to consider flex-shrink:0 on .R (or replace its width by min-width)
body {
background-color: #000;
color: #FFF;
display: flex;
justify-content: center;
}
.wrapper {
margin: 0 1.5rem;
max-width: 40rem;
min-width:0;
}
.fit_content_box {
display: flex;
align-items: center;
}
.L {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.R {
margin-left: 1rem;
flex-shrink:0;
height: 1rem;
width: 1rem;
background-color: #FFF;
}
.overflow {
display: flex;
justify-content: space-between;
}
.overflow>div {
width: 0;
display: flex;
justify-content: center;
}
<body>
<div class="wrapper">
<div class="fit_content_box">
<p class="L">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div class="R"></div>
</div>
<div class="overflow">
<div>
<p>0</p>
</div>
<div>
<p>12</p>
</div>
<div>
<p>24</p>
</div>
</div>
</div>
</body>
If you want the element to remain at least equal to max-width when there is a small amount of text add flex-grow:1:
body {
background-color: #000;
color: #FFF;
display: flex;
justify-content: center;
}
.wrapper {
margin: 0 1.5rem;
max-width: 40rem;
min-width:0;
flex-grow:1;
}
.fit_content_box {
display: flex;
align-items: center;
}
.L {
flex-grow:1;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.R {
margin-left: 1rem;
flex-shrink:0;
height: 1rem;
width: 1rem;
background-color: #FFF;
}
.overflow {
display: flex;
justify-content: space-between;
}
.overflow>div {
width: 0;
display: flex;
justify-content: center;
}
<body>
<div class="wrapper">
<div class="fit_content_box">
<p class="L">Lorem ipsum dolor sit e dolor sit e</p>
<div class="R"></div>
</div>
<div class="overflow">
<div>
<p>0</p>
</div>
<div>
<p>12</p>
</div>
<div>
<p>24</p>
</div>
</div>
</div>
</body>
To better illustrate the (1) here is another example with overflowing margin that you can hardly notice:
.container {
width:200px;
margin:auto;
display:flex;
justify-content:center;
}
.box {
height:50px;
width:100%;
background:red;
}
<div class="container">
<div class="box" style="margin:0 5966px">a_long_text_to_avoid_the_shrink</div>
</div>
<div class="container">
<div class="box">a_long_text_to_avoid_the_shrink</div>
</div>
You can see that we have a long text forcing our element to not shrink (the min-width constraint), the element is taking full width and we are centring the content. This will make the margin overflowing like if there is no margin.
If you break one rule then you will see the effect of the margin.
Remove the long text:
.container {
width:200px;
margin:auto;
display:flex;
justify-content:center;
}
.box {
width:100%;
height:50px;
background:red;
}
<div class="container">
<div class="box" style="margin:0 5966px">a long text to avoid the shrink</div>
</div>
<div class="container">
<div class="box">a long text to avoid the shrink</div>
</div>
Remove the centring:
.container {
width:200px;
margin:auto;
display:flex;
}
.box {
width:100%;
height:50px;
background:red;
}
<div class="container">
<div class="box" style="margin:0 5966px">a_long_text_to_avoid_the_shrink</div>
</div>
<div class="container">
<div class="box">a_long_text_to_avoid_the_shrink</div>
</div>
Make a different margin on each side
.container {
width:200px;
margin:auto;
display:flex;
justify-content:center;
}
.box {
width:100%;
height:50px;
background:red;
}
<div class="container">
<div class="box" style="margin:0 500px 0 400px">a_long_text_to_avoid_the_shrink</div>
</div>
<div class="container">
<div class="box">a_long_text_to_avoid_the_shrink</div>
</div>
(2) The white-space is creating the min-width contraint preventing the element from shrinking.
Here is an exmaple to illustrate:
.body {
display: flex;
justify-content: center;
margin: 10px 100px;
border: 2px solid red;
}
.wrapper {
border: 1px solid;
margin: 0 20px;
}
.box {
display:flex;
}
The below is a logical behavior where the text will wrap and the margin are respected
<div class="body">
<div class="wrapper">
<div class="box">
<div>some long text here some long text here some long text here some long text here</div>
</div>
</div>
</div>
Let's add white-space:nowrap. We add a min-width contraint since we said to the text to never wrap thus our flex element will not shrink and overflow.
<div class="body">
<div class="wrapper">
<div class="box">
<div style="white-space:nowrap">some long text here some long text here some long text here some long text here</div>
</div>
</div>
</div>
If we add width:100% we force its width to be the same as the container BUT the margin aren't included and are kept outside (the text will logically overflow)
<div class="body">
<div class="wrapper" style="width:100%">
<div class="box">
<div style="white-space:nowrap">some long text here some long text here some long text here some long text here</div>
</div>
</div>
</div>
Now if we add min-width:0 we remove the constaint of minimum sizing and we can see the margin again even if we keep width:100% because the element will shrink by default
<div class="body">
<div class="wrapper" style="width:100%;min-width:0">
<div class="box">
<div style="white-space:nowrap">some long text here some long text here some long text here some long text here</div>
</div>
</div>
</div>
The trick is that we are centring the element and applying the same margin on both side which will create the illusion of a collapsing margin but it's a simple overflow of the margin from both sides equally.
Let's change the margin slightly on one side to see a little offset to the other side:
.body {
display: flex;
justify-content: center;
margin: 10px 100px;
border: 2px solid red;
}
.wrapper {
border: 1px solid;
margin: 0 20px 0 40px;
}
.box {
display:flex;
}
The below is a logical behavior where the text will wrap and the margin are respected
<div class="body">
<div class="wrapper">
<div class="box">
<div>some long text here some long text here some long text here some long text here</div>
</div>
</div>
</div>
Let's add white-space:nowrap. We add a min-width contraint since we said to the text to never wrap thus our flex element will not shrink and overflow.
<div class="body">
<div class="wrapper">
<div class="box">
<div style="white-space:nowrap">some long text here some long text here some long text here some long text here</div>
</div>
</div>
</div>
If we add width:100% we force its width to be the same as the container BUT the margin aren't included and are kept outside (the text will logically overflow)
<div class="body">
<div class="wrapper" style="width:100%">
<div class="box">
<div style="white-space:nowrap">some long text here some long text here some long text here some long text here</div>
</div>
</div>
</div>
Now if we add min-width:0 we remove the constaint of minimum sizing and we can see the margin again even if we keep width:100% because the element will shrink by default
<div class="body">
<div class="wrapper" style="width:100%;min-width:0">
<div class="box">
<div style="white-space:nowrap">some long text here some long text here some long text here some long text here</div>
</div>
</div>
</div>

It appears that the source of the problem is white-space: nowrap, which is applied to the content element (.L) inside the first child item (.fit_content_box).
.L {
border: solid 1px #FF0000;
min-width: 0;
flex: 1 0;
overflow: hidden;
white-space: nowrap; <--- trouble maker
text-overflow: ellipsis;
}
If you remove that line of code, your side margins on .wrapper work as expected.
So the key questions are:
Why does the white-space property on a grand-child (.L) collapse the side margins of the grand-parent (.wrapper)?
Why does the white-space property not collapse the side margins when they are applied to the parent (.fit_content_box)?
Why does the overflow property, when applied to the grand-parent (.wrapper), with a value other than visible, allow the margins to hold firm on the grand-child (.L)?
You wrote:
Applying the margins to the first child didn't make it collapse with the parent since it's in a new block formatting context.
Actually, this isn't an issue of conventional margin collapsing, because:
We're talking about horizontal margins, and horizontal margins never collapse, and
We're working inside a flex container, and margins inside a flex container never collapse.
So although a full understanding of the problem may lie in the block (or flex) formatting context, I'm not sure that's why margins on the parent don't collapse.
This is as far as I've gotten on this issue. I'll do more research when I have time. Or maybe somebody else can pick it up from here.

Related

How do I put a p tag under two divs?

So I've two divs positioned next to each other via float left for the left div and float right for the right div. I want my p to appear underneath these two divs. However it just refuses to do that. It always appears at the top of the page or between the two divs. I've already tried setting the two divs to display inline block but then they don't stay next to each other and do a line-break instead. I'm relatively new to HTML and CSS so maybe its just a simple beginners fault but I would be gratefull if someone could help me out.
.p {
background: red;
width: 100%;
}
.tippsboxright {
color: rgb(238, 238, 238);
max-width: 45%;
margin: 0 0 0 5%;
float: right;
font-size: 1.7vw;
padding: 0;
}
.boxleft {
max-width: 50%;
}
<main>
<header>
<h1>My header</h1>
</header>
<div class="content">
<div class="boxleft">
<img src="../images/questionguy.png" alt="Typ mit fragen" class="imgkauftipps">
</div>
<div class="tippsboxright">
<p>
This is the right box with text inside of it.
</p>
</div>
<p class="p">This is the p tag that I want to be at the bottom of the page.</p>
</div>
</main>
You'll want to use CSS flexbox for this instead of float. Put the top divs in a wrapper/container and give the wrapper display: flex. That's basically it, but you can finesse it as I've done in this example:
.wrap {
display: flex;
justify-content: space-between;
}
.wrap div {
width: 100%;
outline: 1px solid red;
}
<div class="wrap">
<div>left</div>
<div>right</div>
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Me non paenitet nullum festiviorem excogitasse ad hoc. Quis aute iure reprehenderit in voluptate velit esse. Quam temere in vitiis, legem sancimus haerentia. Inmensae subtilitatis, obscuris et malesuada fames. Fictum, deserunt mollit anim laborum astutumque!</p>
Or, using the html from your example, except I've moved the <p> tag out of the wrapper. Does the <p> have to be in the wrapper div?
.content {
display: flex;
}
<main>
<header>
<h1>My header</h1>
</header>
<div class="content">
<div class="boxleft">
<img src="../images/questionguy.png" alt="Typ mit fragen" class="imgkauftipps">
</div>
<div class="tippsboxright">
<p>
This is the right box with text inside of it.
</p>
</div>
</div>
<p class="p">This is the p tag that I want to be at the bottom of the page.</p>
</main>
There are several ways to get this type of layout, and while floating is the oldest and most common, it's not really designed for this type of thing. float is designed for text to flow around the block, like you see in magazines. So that's what you see happening: your text is flowing around the floats. There is a way to stop this though: clear. Clear tells text to not flow around left, right, or both floated objects. So you can use that to get the layout you desire:
.p {
background: red;
width: 100%;
clear: both;
}
.tippsboxright {
background: lightyellow;
color: rgb(238, 238, 238);
max-width: 45%;
margin: 0 0 0 5%;
float: right;
font-size: 1.7vw;
padding: 0;
}
.boxleft {
background: lightblue;
max-width: 50%;
float: left;
}
<main>
<header>
<h1>My header</h1>
</header>
<div class="content">
<div class="boxleft">
<img src="../images/questionguy.png" alt="Typ mit fragen" class="imgkauftipps">
</div>
<div class="tippsboxright">
<p>
This is the right box with text inside of it.
</p>
</div>
<p class="p">This is the p tag that I want to be at the bottom of the page.</p>
</div>
</main>
It is however better and easier to use either flex box or grid layouts in this case. They are designed for block style layouts, which seems to be what you want, not flowing text around blocks.

Robustly keeping two divs vertically separated

What's the canonical way to ensure an image and text are vertically separated from one another in a fully responsive way?
Look at this:
Via putting the image and text in separate divs, specifying width and ensuring display:block-inline, I'm able to create the following:
But this isn't perfectly responsive. How? For instance, for really small sizes (sizes that I must support), the image and the text run into one another like below:
There has to be a way to keep them vertically separated along any screen size. Perhaps I should use tables?
Please advise with an illustrative example, preferably with well-support CSS 2.1 attributes since a substantial number of clients I have to cater are Opera Mini browsers with no CSS3 or JS support.
My code is:
<div style="background-color:#E1F5FE;border-radius:10px;padding:10px;overflow:hidden;">
<div style="width:20%;display:inline-block;">
<img src="X.png">
</div>
<div style="width:80%;display:inline-block;float:right;text-align:center;">
Lorem ipsum dolor sit amet, ex eam nulla veritus abhorreant, magna vocent molestiae ea pri, ut eos tritani incorrupte
</div>
</div>
This is a variant of the answers given to this similar SO question. It doesn't really solve my problem.
Simply add width:100% for the image
But check the whole css, on small screens it is better to show the div below each others
.main{
background-color:#E1F5FE;
border-radius:10px;
padding:10px;
overflow:hidden;
}
.main > div{
display:inline-block;
float:left;
text-align:center;
}
.imgDiv{
width:20%;
}
.textDiv{
width:80%;
}
.imgDiv > img{
width:100%;
}
#media screen and (max-width: 450px) {
.imgDiv{
margin: 0 0 20px 25%;
width:50%;
}
.textDiv{
width:100%;
}
}
<div class="main">
<div class="imgDiv">
<img src="https://pbs.twimg.com/profile_images/839721704163155970/LI_TRk1z_400x400.jpg" style="width:100%">
</div>
<div class="textDiv">
Lorem ipsum dolor sit amet, ex eam nulla veritus abhorreant, magna vocent molestiae ea pri, ut eos tritani incorrupte
</div>
</div>
Here's a solution using flex with flex-wrap: wrap to take care of the responsive sizing. At small sizes the icon and text will stack vertically, and at larger sizes the icon and text will be horizontally aligned.
Flex has great support these days, even for the browser you mention.
.main {
display: flex;
flex-wrap: wrap;
flex-direction: row;
}
.imgDiv {
flex: 1 1;
min-width: 80px;
text-align: center;
}
.imgDiv > img {
width: 80%;
height: auto;
max-width: 150px;
line-height: 0px;
}
.textDiv {
flex: 1 1 250px;
display: flex;
}
.textDiv > p {
flex: 1 0 0px;
padding: 0;
margin: 0;
align-self: center;
}
<div class="main">
<div class="imgDiv">
<img src="https://pbs.twimg.com/profile_images/839721704163155970/LI_TRk1z_400x400.jpg">
</div>
<div class="textDiv">
<p>Lorem ipsum dolor sit amet, ex eam nulla veritus abhorreant, magna vocent molestiae ea pri, ut eos tritani incorrupte</p>
</div>
</div>

HTML CSS styling for a fixed div and a flexible div

I want to achieve the following layout where there are two columns, a fixed size one (50px wide) for my icon and a flexible one that stretches the remaining part for my messages. I am using bootstrap 4 with angular2
Currently, I am using the following setup with bootstrap 4 grid layout
<div class="col-1">
<md-icon class="material-icons notification-row-icon">done</md-icon>
</div>
<div class="col-11">
<div class="notification-row-text-div">
<label class="notification-mrow-essage-label">{{message}}</label>
</div>
</div>
But the output is off when the screen is extra small as shown below. I want the icon to be always on the left hand side of the message rather than stacked when the screen gets small. Since the col way seems to create this problem, I am thinking to re-build this from good old html/css way instead. How can I achieve that?
You can use flexbox
.flexbox{
display:flex;
}
.col-1,
.col-11{
border:1px solid;
}
.col-1 {
width: 50px;
}
.col-11 {
flex: 1 1;
}
<div class=flexbox>
<div class="col-1">
<md-icon class="material-icons notification-row-icon">done</md-icon>
</div>
<div class="col-11">
<div class="notification-row-text-div">
<label class="notification-mrow-essage-label">{{message}}</label>
</div>
</div>
</div>
Here's a flexbox solution.
The main property to know in this solution is flex-grow.
It specifies what amount of space inside the flex container the item should take up.
If all items in a flex container had the same value, they'd all be the same width. If only one item like we have in this example has flex-grow applied, it takes up the remaining space of it's container.
If you're unfamiliar with box-sizing and the value border-box, it includes padding and borders with an elements width assignment instead of them being added in addition to the assigned width. So if you tell and element to be 200px wide and have 10px of padding, it's 200px wide. Not 220px.
#import url( 'https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css' );
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.container {
width: 90%;
margin: 0 auto;
}
.row {
display: flex;
align-items: flex-start;
margin-left: -5px;
margin-right: -5px;
}
.col {
padding: 5px;
}
.col.fixed {
width: 50px;
}
.col.fill {
flex-grow: 1;
}
p {
margin: 0 0 1rem;
}
<div class="container">
<div class="row">
<div class="col fixed">
<i class="fa fa-rocket"></i>
</div>
<div class="col fill">
<p>
Bring a spring upon her cable handsomely gibbet Corsair scuttle prow Buccaneer nipper. Gun jack clap of thunder port holystone killick bilge water chandler. Gunwalls Cat o'nine tails lookout careen Jack Tar salmagundi boom mutiny.
</p>
</div>
</div>
</div>
You could achieve this without multiple columns...
.icon {
width: 3em; /* change as you need */
display: inline-block;
}
.notification-row-text-div {
display: inline-block;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet" />
<div class="container">
<div class="row">
<div class="col-12">
<span class="icon">▣</span>
<div class="notification-row-text-div">
<label class="notification-mrow-essage-label">John Doe</label>
</div>
</div>
</div>
</div>
Flexbox is built into Bootstrap 4 so you don't need any extra CSS other than the fixed width column.
.fixed {
width: 50px;
}
Then just use the auto-layout col class to consume the remaining space:
<div class="row">
<div class="fixed">
icon
</div>
<div class="col">
..
</div>
</div>
The col class already uses flex-grow.
Demo: http://www.codeply.com/go/iprwiDJhgy
You can try this simple code. It is fully tested. I hope it will help you.
HTML:
<div class="container">
<div class="row">
<div class="col fixed">
<span>©</span>
</div>
<div class="col fill">
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmodtempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</p>
</div>
</div>
</div>
CSS:
<style>
.col.fixed {
width:50px;
float:left;
}
.col.fill {
display: block;
margin-left: 50px;
}
</style>

Why isn't the parent adjusting it's width to content?

I might just be really tired but I can't for the life of me figure out why display: inline-block isn't working to make the parent's width adjust to the size of it's contents. I've tried searching for other solutions but every resource I've found says adding inline-block to the parent should do the trick.
In the example below, I am trying to make the blue square only extend to the edge of the green square, and then ultimately center the contents via margin: 0 auto;:
#intro {
height: 400px;
background-color: red;
}
.slide-txt {
display: inline-block;
width: 30%;
background-color: lime;
}
.slide-box {
display: inline-block;
margin: 0 auto;
background-color: blue;
}
<section id="intro" class="image-slider">
<div class="container" id="intro-slide">
<div class="slide-box">
<img src="http://www.jkoffset.com/assets/images/Packaging1.jpg" alt="same-box-slide" width="150px">
<div class="slide-txt">
<h1 class="title">Headline <span>Goes Here</span></h1>
<div class="caption"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
<a class="btn" href="#">
Learn More
</a>
</div>
</div>
</div>
</div>
</section>
https://jsfiddle.net/eam0mk47/
Using width:30%; in the div child (.slide-txt) will make the parent div expand to fill the other 70%, so to avoid that and make it adjust according to content you need to use px instead of % in the div child.
In that red #intro is a div with the class .container ... this element has padding left and right via bootstrap.
Just remove that padding:
https://jsfiddle.net/eam0mk47/1/
#intro .container {
padding: 0px;
}
Or don't use that class there.

divs collapsing around header

I have a few nested divs:
<div id="wrapper">
<div id="header">
<!-- a bunch of float divs here -->
</div>
<div id="body">
<div id="content">
<!-- a bunch of html controls here -->
</div>
</div>
</div>
wrapper style: width: 780px; margin:
20px auto; border: solid black 5px;
header style: position: relative;
min-height: 125px;
body style: position: relative;
content style: position: absolute;
left: 50px; top: 0px;
I have a bunch of html elements in the content div and for some reason the body div and the wrapper div are collapsing around the header and the content div hangs out on its own if I don't set a fixed height for the body div. The only float elements I have are in the header.
EDIT:
If I remove the content div (and drop the html elements directly in body) the body div stops collapsing! Trying to understand why - guess it's due to the position: absolute of the content div.
Any clue why this is happening and how to solve?
I had a look at this question but It doesn't seem to work for me (or maybe I am clearing inthe wrong place...).
You don't really need to use absolute or relative positioning in this case.
The following achieves what you need with a minimal amount of css wrangling.
Colours becuase I like colour, and so should you!
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>Page Title</title>
<style type="text/css" media="screen">
#wrapper {
width: 780px;
margin: 20px auto;
border: solid black 5px;
}
#header {
min-height: 125px;
overflow:hidden;
}
#body {
background-color:red;
}
#content {
margin-left: 50px;
margin-top: 0px;
background-color:pink;
}
.floatie { float:left; width:40px; height :40px;
margin:5px; background-color:#fe0;}
</style>
</head>
<body>
<div id="wrapper">
<div id="header">
<div class="floatie"></div>
<div class="floatie"></div>
<div class="floatie"></div>
<div class="floatie"></div>
<div class="floatie"></div>
<div class="floatie"></div>
<div class="floatie"></div>
</div>
<div id="body">
<div id="content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.</p>
</div>
</div>
</div>
</body>
</html>
Try this. Note: the overflow hidden on the header div solves the need for a clearing div. Note sure why you're using relative+absolute positioning for the content though. That's better handled with margins imho.
<html>
<head>
<title>Layout</title>
<style type="text/css">
#wrapper { width: 780px; margin: 20px auto; border: solid black 5px; }
#header { overflow: hidden; background-color: yellow; }
#header div { float: right; border: 2px solid red; }
#body { position: relative; }
#content { position: absolute; left: 50px; top: 0px; }
</style>
</head>
<body>
<div id="wrapper">
<div id="header">
<div>One</div>
<div>Two</div>
<div>Three</div>
</div>
<div id="body">
<div id="content">
<p>This is some text</p>
</div>
</div>
</div>
</body>
</html>
I use this style for clearing elements:
.Clear { clear: both; height: 0; overflow: hidden; }
Place a clearing div in the header, to give the header element size:
<div id="wrapper">
<div id="header">
<!-- a bunch of float divs here -->
<div class="Clear"></div>
</div>
<div id="body">
<div id="content">
<!-- a bunch of html controls here -->
</div>
</div>
</div>
Setting the height of the clearing element to zero causes it to take up no space by itself. The overflow style is so that IE will not give it a height eventhough the height is set to zero. IE has a strange idea that every element has to be at least one character high, setting overflow:hidden; keeps the height at zero eventhough the content of the element is one character high in IE.
If you want #content to show up within the border boundaries of #wrapper try this swap on for size, after you remove position:relative from #body (or remove that DIV entirely):
#header{position: relative; overflow:hidden; clear:both;}
#content{position:relative; left:50px; top:0px;}
That way you will be able to see #content show up within the wrapper but beneath #header.
May be happening because there really isn't anything for #content to stick out from under. #header, when it was set to relative, kind of disappears for the below, even if #body was then set to absolute with descendants of it set to relative.
Changing up #content from position:absolute to position:relative will have it come under the previous DIV, which in this case was #header.
Try clearing after your floated elements within the header.
<div id="wrapper">
<div id="header">
<!-- a bunch of float divs here -->
<div style="clear:both;"></div> <!-- Or use a clearfix... -->
</div>
<div id="body">
<div id="content">
<!-- a bunch of html controls here -->
</div>
</div>
</div>
As long as the clearing element is within the containing div it should accomplish what you want.
Add style "clear: both" to your div with "body" id. You could also add a div with this style just after "bunch of float divs" and before closing tag of header div.
When you want to clear something you also need to float that element to make it work properly. So you will need.
#header { clear: both; float: left; }
#body { clear: both; float: left; }
I'm not a fan of using "clear:both" if it's not totally needed. A better solution is setting the "overflow" property of the collapsing DIV to "auto".
Try something like:
#header { float: left; overflow: auto; }