skip to Main Content

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.

2

Answers


  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.

    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search