admin管理员组

文章数量:1123097

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

Stackblitz to show my issue

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.

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

Stackblitz to show my issue

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.

Share Improve this question edited 4 hours ago amanda asked 4 hours ago amandaamanda 9946 silver badges11 bronze badges 3
  • CSS 2 explicitly did not define this. Webkit seems to have changed to be consistent with Gecko and Blink. As far as I know, CSS 3 doesn't clarify it anywhere, but I'd be interested if anyone knows better. – Alohci Commented 3 hours ago
  • @Alohci was this a gradual change or with the 18.2 update? With 18.2, Webkit changed something that's different from Gecko. This bug only appeared in Chrome and Safari after the update. – amanda Commented 2 hours ago
  • I do not know anything about the specific Webkit changes. I'm just saying that it matches the behaviour I see in Gecko and Blink, and further if you read my answer, it gives a plausible reason why the new Webkit behavior makes sense. – Alohci Commented 2 hours ago
Add a comment  | 

2 Answers 2

Reset to default 1

overflow:auto causes the .content div to establish a block formatting context. What the CSS 2 specification says is:

The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with overflow other than visible) must not overlap the margin box of any floats in the same block formatting context as the element itself. If necessary, implementations should clear the said element by placing it below any preceding floats, but may place it adjacent to such floats if there is sufficient space. They may even make the border box of said element narrower than defined by section 10.3.3. CSS 2 does not define when a UA may put said element next to the float or by how much said element may become narrower.

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 adding margin or padding, you can modify the CSS as follows:

Option 1: Clearfix Add a clearfix to the .wrapper so that it properly contains its floated child.

.wrapper::after {
  content: "";
  display: block;
  clear: both;
}

Option 2: Use clear: left on .content This ensures the .content starts below the floated .header.

.content {
  clear: left;
  overflow: auto;
}

Option 3: Avoid Floating Altogether Instead of using float: left for the .header, use display: block (default behavior) to make the layout simpler.

.header {
  width: 100%;
}

Corrected Code:

<div class="wrapper">
  <div class="header">Header</div>
  <div class="content">Content</div>
</div>
.header {
  float: left;
  width: 100%;
}

.content {
  clear: left;
  display: block;
  overflow: auto;
}

This ensures the .content flows correctly beneath the .header without relying on arbitrary margins or padding.

本文标签: htmlWhy will a div39s width collapse to 0 when it doesn39t have a margin or paddingStack Overflow