I have a header div and content div. Header is float: left
and width: 100%
. Content is display: block
and overflow: auto
. Content div width collapses to 0, and it stays to the right of the header. It won’t flow underneath.
<div class="wrapper">
<div class="header">Header</div>
<div class="content">Content</div>
</div>
.header {
float: left;
width: 100%;
}
.content {
display: block;
overflow: auto;
}
However, if I add margin: 1px
or padding: 1px
to .content
, it will grow to its auto width and flow under .header
Why is this? The div has content in it, so what is it about margin and padding that helps it grow to its width?
Also, it works if I set overflow to visible, but I learned from this answer that that is because overflow: auto sets a new block flow context.
And my further question: After updating to Webkit 18.2, now margin will not fix the width. Only padding will make the element grow to its full width.
After doing some research, I’ve theorized that its because WebKit made some changes to their rendering intelligence. However, I can find no details on the changes they made there in the 18.2 Release Notes or anywhere on the web yet.
I know how to fix the bug, but I want to know WHY. It was working fine before 18.2 because the content had a margin, but no padding. Now in 18.2, it is broken unless it has padding.
2
Answers
overflow:auto
causes the.content
div to establish a block formatting context. What the CSS 2 specification says is:So vagueness prevails. But one of the rules that was added by CSS box-sizing was that the width of an element’s content box was floored at zero. i.e. negative widths of the content box are not allowed.
So, let’s assume that the rule is that the border box width of the BFC can in the presence of a float shrink until it reaches zero, but no further. In that case, providing the BFC has no inline border or padding, then the BFC’s width is zero and it can fit alongside the float, so it does so.
But if the BFC contains any inline padding or border at all, with the content-box width floored at zero, then the BFC must have some positive width, and cannot fit alongside the float. So it is placed below the float.
Note that it is the border box that shrinks, so adding inline margin should have no effect.
To ensure the
.content
div behaves as intended without relying on the hack of addingmargin
orpadding
, you can modify theCSS
as follows:Option 1: Clearfix
Add a clearfix to the
.wrapper
so that it properly contains its floated child.Option 2: Use clear: left on
.content
This ensures the
.content
starts below the floated.header
.Option 3: Avoid Floating Altogether
Instead of using float: left for the
.header
, usedisplay: block
(default behavior) to make the layout simpler.Corrected Code:
This ensures the
.content
flows correctly beneath the.header
without relying on arbitrary margins or padding.