5

I am reading CSS specs, the section on Visual Formatting Model and trying to understand what is the difference between these two terms: containing block and block container box.

What confuses me is the variation of words that are used for what seems to be completely different concepts:

  • box vs block
  • containing vs container

Is block same as box when talking about visual formatting CSS? If not, what is the difference? Are both of these something that is "visible" on the screen?

In general, how should I think when I see block in the specification? Also what should first come to my mind when I read box in the specs?

Some helpful metaphors or analogies for these concepts would be very helpful to create a mental model.

Fabrizio Bertoglio
  • 5,890
  • 4
  • 16
  • 57
mlst
  • 2,688
  • 7
  • 27
  • 57
  • 1
    a block container box can be a containing block for another box ... we say for example Box A is the *containing block* of Box B. The *containing block* is used to identify the box we will use as a reference for some calculation. – Temani Afif May 17 '19 at 12:18
  • I think a *box* is the generic term and we use block when it's block and inline when it's inline ... from the same spec `The three terms "block-level box," "block container box," and "block box" are sometimes abbreviated as "block" where unambiguous.` – Temani Afif May 17 '19 at 12:22
  • Ok... I see there is a "inline-level box" in the specs but there seems not to be such a thing as "inline container box". Why is that? – mlst May 17 '19 at 12:28
  • Probably *block container* is also generic and can apply to inline element too. I know for sure that we have *inline-level box* and *block-level box* that are clear and also block formatting contexts and inline formatting contexts – Temani Afif May 17 '19 at 12:33
  • 1
    Possible duplicate of https://stackoverflow.com/questions/30883857/css-spec-block-level-box-block-container-box-and-block-box – LuVu May 17 '19 at 12:58
  • Possible duplicate of [CSS Spec: block-level box, block container box and block box](https://stackoverflow.com/questions/30883857/css-spec-block-level-box-block-container-box-and-block-box) – LuVu May 17 '19 at 12:58
  • 1
    @luka98v - although that q&a covers a lot of the ground, it does not mention the term "containing block" at all, so not a duplicate. – Alohci May 17 '19 at 13:06
  • 1
    @luka98v the OP asked this question after being redirect to that one: https://stackoverflow.com/q/56169484/8620333 – Temani Afif May 17 '19 at 13:14
  • One thing that might not be clear: "block container box" means a box that can be a "containing block" box, not a box that can contain blocks. Hence an "inline container block" would equate to a box that could be a "containing inline" box. Neither such concept exists in CSS. – Alohci May 17 '19 at 14:30
  • @Alohci there is a bounty on the question now, you can probably add a detailed answer to explain it. He's also asking another similar question here: https://stackoverflow.com/q/56238082/8620333 – Temani Afif May 21 '19 at 12:55
  • @TemaniAfif - Do you have any thoughts on mist's first comment to my answer below? I have a theory of what the spec might be trying to say, but I can't say I'm very confident. Might post a new question otherwise. – Alohci May 22 '19 at 15:52
  • @Alohci not really sure but I think a box (which is necessarely a DOM element) will create/establish a rectangular area that's why we can say *all boxes are rectangular areas* BUT probably we may have some rectangular areas created differently without a box like for example the initial containing block which is a rectangle and we don't have any dom element (any box to reference it) and also the tracks created within a CSS Grid. Those tracks where element can belong have width/height are *probably* called rectangle but we don't have any box for them. – Temani Afif May 22 '19 at 16:13

1 Answers1

9

Let's start at the beginning. CSS is almost entirely about boxes. A box is just a rectangular area of the canvas. The canvas is the entire 2D space on which everything is drawn.

CSS Boxes have a whole range of flavours. Block boxes, block-level boxes, inline boxes, inline-level boxes, content boxes, padding boxes, border boxes, margin boxes, table boxes, line boxes, flex boxes, and so on. They're all just rectangular areas.

So a block is just one type of box. Many of the above boxes are characterized by two behaviours - how they are laid out relative to their containers and peers, and how their content is laid out within them. The CSS-display spec refers to these as display-outside and display-inside respectively

Display-outside refers to the "*-level" nature of the boxes. They're not what we're interested in here.

All block boxes, and some inline-level boxes are block container boxes. A block container box is a box of type "block container", not necessarily a box that contains blocks. Block containers that are not block-level boxes include those that are display:inline-block and display:table-cell

The "block" in "block container" refers to its display-inside behaviour. Block boxes are laid out vertically within them and text flows horizontally, ordinarily limited by its edges of the rectangle.

So a "block container box" is a type of box. In contrast, "containing block" refers to a specific box. Each box defined on the canvas has exactly one containing block, with just one exception, called the initial containing block, which has no containing block.

Only a box of type "block container box" can be a box's containing block.

Time for an example. Let's suppose we have the HTML below: I'm deliberately going to use <span> elements throughout, because this is all about CSS, and I don't want to confuse with HTML behaviour.

<span id="level1">
  foo
  <span id="level2">
    bar
    <span id="level3">
      baz
      <span id="level4">
        qux
      </span>
    </span>
  </span>
</span>

The CSS is very simple. Just

#level1 { display:inline-block }

The other spans are the CSS default display setting, "inline".

Now, consider the #level4 span. Its parent is the '#level3' span, which is display:inline so the '#level3' span does not form a block container box. Similarly, the #level2 span also does not form a block container box. But the #level1 element is display:inline-block. That forms an inline-level box, but one that is a block container box. (This is what "inline-block" means).

So the containing block for all the inline boxes formed by the #level2, #level3, #level4 spans and their text content is the block container box formed by the #level1 element's box.

Alohci
  • 78,296
  • 16
  • 112
  • 156
  • Thanks for the thorough answer, really appreciate it. I will need some time to digest all this. I am still confused by the terminology that is not precise enough. For example, you say "A box is just a rectangular area of the canvas." but the specs (https://www.w3.org/TR/css-display/#containing-block) says "Notably, a "containing block" is not a box (it is a rectangle), however it is often derived from the dimensions of a box." so it seems that specs make distinction between "box" and "rectangular" as CSS concepts. – mlst May 22 '19 at 12:39
  • Another example is when you say "So a block is just one type of box.", but in the list of box flavours you provided (assuming flavours == types) there is no "block" per-se, there are "block boxes" and "block-level boxes". So is "block" (as a word used on its own) a synonym for "block box" or "block-level box", or it encompasses both? And what exactly is the main characteristics of a box that is of type "block"? What should first come to my mind when I think of a "block" in CSS terms? – mlst May 22 '19 at 12:40
  • Sorry if I am too nitpicking but it's so confusing :(. On the bright side, the example you provided is somehow and paradoxically completely understandable for me. – mlst May 22 '19 at 12:40
  • That first comment is a cracker, and I'll need to investigate since it seems to contradict CSS 2.2. In the meantime I see that there is a note which says "Many of the CSS specs were written before this terminology was ironed out, or refer to things incorrectly, so view older specs with caution when they’re using these terms. It should be possible to infer from context which term they really mean." – Alohci May 22 '19 at 12:57
  • For the second comment, CSS 2.2 says 'The three terms "block-level box," "block container box," and "block box" are sometimes abbreviated as "block" where unambiguous.'. So you have to work out which one the spec means from its context. – Alohci May 22 '19 at 13:06
  • @mlst - OK, Here's what I think. CSS has a notion of a "Box". It also calls lots of rectangles "box"es which don't comply with this notion. To CSS, this notion of a box is the russian doll arrangement of rectangular areas as described by the box model, It includes the content, padding, border and margin area rectangles. The combination of the 4 is a "box". But it also calls the areas the "content box", "padding box", "border box" & "margin box". None these are "box"es according to the russian doll notion. They're just rectangles. Similarly, line boxes and page boxes are not "box"es. – Alohci May 23 '19 at 02:06
  • So the same applies to the containing block. The containing block is just one of those rectangles, sometimes the content box, sometimes the padding box. – Alohci May 23 '19 at 02:09
  • Block-level boxes, inline-level boxes, table-cell boxes, flex boxes: each of these do comply with the russian doll notion of a "box". – Alohci May 23 '19 at 02:58
  • Thank you very much Alohci. I will continue with digesting this although I feel a bit nausea. The sole fact we are having this discussion is a clear indicator to me that CSS specification is not very well written. It's no wonder that so many people think "CSS is hard" when the primary "source of truth" is so loosely written, leaving so much room for arbitrary interpretation. As someone with 15+ years of backend development, where things are pretty much clear and well defined, I am even more puzzled with how CSS authors and expert groups in the field couldn't do a better job with CSS specs. – mlst May 23 '19 at 09:59
  • @mlst- actually, I have the greatest respect for the CSS 2.x authors. A great many, possibly even most, of the concepts described there, such as normal flow, the box model, floats, line boxes, vertical alignment, tables, etc, pre-date CSS. The spec is largely an attempt to bring a semblance of order and reason to the often bizarre behaviours that the early browsers had. It's a pity that the CSS3 specs don't tidy up issues like this one better, but it's by no means an easy task. – Alohci May 23 '19 at 12:30
  • 1
    ^ The most extreme example thereof can be seen in the css-tables spec. It's a running joke within the CSSWG that no one wants to touch it with a 10-foot pole, there be dragons, etc, because of just how "insane" (exact words) perennial browser behavior is. – BoltClock Sep 02 '19 at 09:13