sun qingyao sun qingyao - 2 months ago 11
CSS Question

New BFC "clearing" floating boxes

As the example shows, applying

display: inline-block;
to the containing block seems to "clear" the floating box within.



.wrapper-inline-block {
display: inline-block;
}
.left-column {
background-color: teal;
float: left;
}

<div class="wrapper-inline-block">
<div class="left-column">
<p>Float</p>
</div>
<p>Non-float</p>
</div>

<div class="wrapper">
<div class="left-column">
<p>Float</p>
</div>
<p>Non-float</p>
</div>





I have no idea how this happens. All what I know is that
display: inline-block;
creates a new block formatting context.

My question is: how does the new BFC "clear" floating boxes within?

Answer

That's because inline-blocks with the default width: auto are sized according to the shrink-to-fit algorithm. CSS2.1 does not fully define how that algorithm should handle floating contents, but it seems browsers do this:

  1. The inline-block is sized ignoring floats
  2. The line boxes inside the inline-block are as wide as the inline-block
  3. The float shrinks the line boxes
  4. Therefore, the non-floating contents no longer fit in the shrunk space, so the wrap to the next line.

Note there is no clearing, if you make the inline-block wide enough, the text will appear next to the float.

.wrapper.inline-block {
  display: inline-block;
}
.w400 {
  width: 400px;
}
.wrapper {
  border: 1px solid;
}
.left-column {
  background-color: teal;
  float: left;
}
<p>Shrink-to-fit inline-block:</p>
<div class="wrapper inline-block">
  <div class="left-column">
    <p>Float</p>
  </div>
  <p>Non-float</p>
</div>
<p>Explicit width inline-block:</p>
<div class="wrapper inline-blockw w400">
  <div class="left-column">
    <p>Float</p>
  </div>
  <p>Non-float</p>
</div>
<p>Fill-available block:</p>
<div class="wrapper">
  <div class="left-column">
    <p>Float</p>
  </div>
  <p>Non-float</p>
</div>