10

.wrapper {
  width: 500px;
}

.image {
  display: inline-block;
  width: 50%;
  height: 100px;
  background: red;
}

.image1 {
  float: left;
  width: 50%;
  height: 50px;
  background: yellow;
}

.image2 {
  float: left;
  width: 50%;
  height: 50px;
  background: red;
}
<div class="wrapper">
  <div class="image"></div>
  <div class="image1"></div>
  <div class="image2"></div>
</div>

https://jsfiddle.net/8akzqx3p/

What I originally thought was that image2 was just below image1. However, it is far below. I found this reason in the W3C specs, but I don't know what this means.

https://www.w3.org/TR/CSS21/visuren.html#floats

If there is not enough horizontal room for the float, it is shifted downward until either it fits or there are no more floats present.

But I don't know what it means, especially "either it fits or there are no more floats present"

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
newbieeyo
  • 663
  • 4
  • 12

1 Answers1

7

Relationship between the floated boxes, the inline-block box, the line box and the anonymous block box

To understand this, we need to take both the part you quoted and its preceding paragraph. Together they say:

A floated box is shifted to the left or right until its outer edge touches the containing block edge or the outer edge of another float. If there is a line box, the outer top of the floated box is aligned with the top of the current line box.

If there is not enough horizontal room for the float, it is shifted downward until either it fits or there are no more floats present.

Which means:

If there is a line box ...

Initially the first inline-block image causes a line box to exist which is the height of the image vertically aligned with the line box's strut. (So just slightly taller than the image alone). Because there are other elements inside the block formatting context (the floats) the line box will be wrapped in an anonymous block box.

So the first floated image just fits alongside, and its top is aligned with the top of that line box.

But there's no space for a second floated image that both can be aligned with the top of that line box and alongside the inline-block image. So this second floated image must be placed after that line box, and after the anonymous block box that wraps it. There is no second line box so

it is shifted downward until either it fits ...

We're in a block formatting context here, so after a block box, means immediately following it on the block axis. There it fits, so that's where it is placed.

... or there are no more floats present.

This is not in play in your example. It allows for the case where the width of the float is defined as having a width of, for example, 110% of its containing block. It'll never fit, but can be placed immediately below the point where there are no preceding floats alongside it.

Community
  • 1
  • 1
Alohci
  • 78,296
  • 16
  • 112
  • 156
  • why there is an anonymous block box? aren't we in an inline formatting context because we have inline-* elements? if the float element is taller than the inline-* one we may have many line box floating around the float, in this case we will also have an anonymous block box surrounding the float and all the linebox on the right? – Temani Afif May 13 '20 at 19:36
  • @TemaniAfif - remember that from [CSS 2.2, 9.2.1.1 Anonymous block boxes](https://www.w3.org/TR/CSS22/visuren.html#anonymous-block-level) a block container (e.g. the wrapper) can *only* contain either all inline boxes or all blook boxes. We know from [CSS 9.7 point 3](https://www.w3.org/TR/CSS22/visuren.html#dis-pos-flo) that floats are blockified, so without the anonymous block, the wrapper would contain both inline and block boxes. So the anonymous block is added to fix it. – Alohci May 13 '20 at 22:37
  • What might be misleading from the diagram is that the first float isn't contained by the anonymous block box either, it just shares an aligned top edge. The anonymous block, like regular blocks, stretches from the left edge of the containing block to the right edge, but the line box it contains is shortened so as to not overlap the float. So neither float has an anonymous block box surrounding it, just the inline content has one. – Alohci May 13 '20 at 22:37
  • Intresting, so if I consider this example: https://jsfiddle.net/6xc2prv0/ can I say that I have 2 anonymous block box? (one that contain the float and two line box and the other contain the remaining line boxes) Or they are 3 (each of the last 2 line box in a separate anonymous box) ? – Temani Afif May 13 '20 at 22:55
  • @TemaniAfif - neither. There's just two block boxes. The outer one is generated by the container div, so not anonymous, and contains the float and a single inner anonymous block box. This inner block box establishes an inline formatting context and contains all four line boxes. – Alohci May 13 '20 at 23:44
  • so like that: https://jsfiddle.net/wL4o9mn5/? Technically the red block cointain the float + the anonymous block (the blue) BUT the float doesn't belong to the blue one and simply overlap it because it's floating? and the blue one contain only the lines boxes that wrap around the space created by the float element? – Temani Afif May 13 '20 at 23:56
  • Thanks for your patience, I got it I guess. It's like I add an extra div to surround only the inline elements and I leave the float outside: https://jsfiddle.net/wL4o9mn5/1/ .. here it's not more anonymous but it behave exactly the same and we can later apply overflow:auto to it :https://jsfiddle.net/wL4o9mn5/2/ and we get back to your previous explanation about IFC and BFC that can be on the same element: https://stackoverflow.com/a/56247649/8620333 :) – Temani Afif May 14 '20 at 00:03