Do Inline Elements Establish a Line Box for Their Content

Do Inline elements establish a Line Box for their content?

Your heading and first paragraph ask two different questions:

  • Do Inline elements establish a Line Box for their content?
  • [Are] line boxes are formed inside inline-level elements?

They have different answers, "No", and "Sometimes" respectively, so the first thing that needs to be dealt with is the -level suffix.

An inline-level box is a broader category than an inline box. A span element which contains only text generates, by default, a sequence of inline boxes sufficient to lay out that text content over as many lines as is necessary. All inline boxes are also inline-level boxes, but the opposite is not true. Elements whose computed display is inline-block, inline-table, inline-flex and inline-grid all generate boxes that are inline-level, but are not inline boxes.

Similar applies to block versus block-level. Block-level describes how a box lays out relative to its parents and siblings. Block containers are boxes in which their child boxes are laid out either as sequence of block-level boxes, or within a stack of line boxes, and never as a mixture of both.

Elements whose computed display value is block, flow-root and list-item and are being laid out in a block formatting context (i.e. they're not a flex item or a grid item) generate a single box that is both block-level and a block container. These are called block boxes.

But boxes generated for elements that have computed display values of table, flex, and grid are block-level, but they are not block containers. Their descendants are laid out using different rules. These are not block boxes.

Conversely, elements that have computed display values of inline-block and table-cell generate boxes that are block containers but they are not block-level. They interact with their parents and siblings differently than block level boxes do.

So, specifically, inline-block boxes, which are inline-level, contain either a sequence of block-level boxes, or a stack of line boxes in which other inline-level boxes are laid out.


Now, an inline box can contain other inline-level boxes, but that does not make it a block container, even if one of those inline-level boxes is itself a block container. The block container of the inline box and all its descendant inline-level boxes that are not themselves inside other formatting contexts is the nearest ancestor that is a block container.

So, suppose we have this tree of boxes

 display:block                     block level, block container
| ↑ ↑
+ - display:inline inline level ---------+ | \
| | |- In the same line box
+ - display:inline-block inline level, block container /
| ↑
+ some text anonymous inline box --+ in a line box

where the arrows point from inline-level boxes to their block container.

Box Model for Inline Elements

For the second question you may refer to this part of the specification:

The 'height' property does not apply. The height of the content area
should be based on the font, but this specification does not specify
how. A UA may, e.g., use the em-box or the maximum ascender and
descender of the font. (The latter would ensure that glyphs with parts
above or below the em-box still fall within the content area, but
leads to differently sized boxes for different fonts; the former would
ensure authors can control background styling relative to the
'line-height', but leads to glyphs painting outside their content
area.)

The vertical padding, border and margin of an inline, non-replaced box
start at the top and bottom of the content area, and has nothing to do
with the 'line-height'. But only the 'line-height' is used when
calculating the height of the line box.

.test {  margin: 0 10px;  padding: 20px;  border: 5px solid blue;}
div { border:1px solid red; margin:50px 0;}
<div><span class="test">test2test2test2test2test2test2test2 test</span></div>
<div><span class="test">test2test2test2test2test2test2test2 test st2test2test2test2 test st2test2test2test2 test st2test2test2test2 test</span></div>

<div><span class="test" style="line-height:50px;">test2test2test2test2test2test2test2 test2test2</span></div>
<div><span class="test" style="line-height:50px;">test2test2test2test2test2test2test2 test2test2 test2test2test2test2test2test2test2 test2test2</span></div>

When does a box establish an inline formatting context?

To answer your question, I reread Section 9.2.1 of the CSS 2.1 spec.

Based on my reading, you have your answer: the inline formatting context is triggered when a block container box contains only inline elements.

In contrast to a block formatting context that can be triggered explicitly (for example, setting overflow: hidden to a block-level element), an inline formatting context cannot be triggered explicitly.

Inline formatting contexts appear to always exist as descendant block boxes within a "principal block-level box", and these descendant block boxes may be anonymous.

I offer the following description as a mental model for understanding block/inline formatting contexts.

A block-level element (e.g. a <div>) fulfills two responsibilities: one, positioning, and two, content formatting.

When dealing with positioning, a block-level element acts as a "block-level box".

When dealing with formatting, a block-level element acts as a "block container box".

Acting as a "block-level box", the block-element behaves according to the type of positioning (static, absolute, relative, fixed) specified by the position property.

Acting as a "block container box", the block-element establishes a block-formatting context if the block-element has at least one child block-level element. If all the child elements are inline-level boxes, then an inline-formatting context is established.

If the "block container box" contains text and block elements, then the text is treated as being contained in one or more anonymous block-level boxes, and a block-formatting context is established.

Aside
The CSS spec is not exactly light reading. I have reread Chapters 9 and 10 several times and I have yet to come up with a plain-English translation.

Box model properties on anonymous inline boxes

No; since margins, borders and padding are not inherited properties, and you cannot style anonymous boxes directly with CSS (not even with the universal selector, or pseudo-elements), anonymous inline boxes cannot have margins, borders or padding.

Line boxes cannot have margins, borders or padding either.

Inline anonymous boxes?

Section 9.2.2.1 in the Visual Formatting Model actually has an almost identical example to yours, e.g.

Any text that is directly contained inside a block container element (not inside an inline element) must be treated as an anonymous inline element.

In a document with HTML markup like this:

<p>Some <em>emphasized</em> text</p>

the <p> generates a block box, with several inline boxes inside it. The box for "emphasized" is an inline box generated by an inline element (<em>), but the other boxes ("Some" and "text") are inline boxes generated by a block-level element (<p>). The latter are called anonymous inline boxes, because they do not have an associated inline-level element.

What you're seeing in Chrome's developer tools is the display value for the element that the anonymous boxes lives in, not of the inline boxes themselves. They're all actually inline boxes, but "In 1912" & "sank on her maiden voyage" would be anonymous while the <em> element would create a non-anonymous inline box as it is an inline-level element.

Are Block-Level Boxes Enclosed in Line Boxes?

I'm not actually sure if a block-level box can be said to be adjoining to a line box (or vice versa). However, in your example, there are in fact two line boxes — one that is generated by div.one when formatting its inline contents by establishing an inline formatting context, and another that is generated by the body element when formatting span.two (and its span.three child) — and the line box inside div.one can be said to be adjoining to the one containing span.two and span.three.

For the purposes of drawing inline boxes, it doesn't matter which block container is generating each line box that's adjoining to those containing those inline boxes. It doesn't even matter whether any of the block containers also establishes a block formatting context. That is why you see the inline box of span.three bleed into the line box inside div.one.

A block-level box cannot directly coexist with a line box, and by definition of "block-level" it cannot be enclosed in a line box either (to answer your title). In your example, the line box on which the spans are rendered resides in an anonymous block box that is then laid out as a sibling of the div. That anonymous block box establishes its own inline formatting context for the spans, just like the div does for its text.

Inline elements and line-height

This might be confusing because in the inline formatting model there are different heights.

Height of an inline box

An element with display: inline generates an inline box:

An inline box is one that is both inline-level and whose contents
participate in its containing inline formatting context. A
non-replaced element with a display value of inline generates an
inline box.

And line-height determines the height of that box:

The height of the inline box encloses all glyphs and their
half-leading on each side and is thus exactly 'line-height'

Therefore, your box is, in fact, 15px tall.

Height of a line box

There are also line boxes:

In an inline formatting context, boxes are laid out horizontally, one
after the other, beginning at the top of a containing block.
Horizontal margins, borders, and padding are respected between these
boxes. The boxes may be aligned vertically in different ways: their
bottoms or tops may be aligned, or the baselines of text within them
may be aligned. The rectangular area that contains the boxes that form
a line is called a line box.

The height of a line box is determined by the rules given in the
section on line height calculations.

In case a line box only contains non-replaced inline boxes with the same line-height and vertical-align, those rules say that the height of the line box will be given by line-height.

So in your case, this is also 15px.

Height of the content area of an inline box

However, the developer tools of your browser said 18px. That's because those 18px are the height of the content area. It's also this content area (together with paddings) which is painted by the green background.

Note those 18px might vary because CSS 2.1 doesn't specify an algorithm:

The height of the content area should be based on the font, but this
specification does not specify how. A UA may, e.g., use the em-box or
the maximum ascender and descender of the font. (The latter would
ensure that glyphs with parts above or below the em-box still fall
within the content area, but leads to differently sized boxes for
different fonts; the former would ensure authors can control
background styling relative to the 'line-height', but leads to glyphs
painting outside their content area.)

If an UA implements the first suggestion, the content height will be given by font-size, which determines the em-box. This would what you expected, with the green box being 15px tall.

However, most UAs don't seem to do that. That means that, probably, the height will be the height of the tallest glyph in the font-family and font-size used.

But using a font-size value of 15px doesn't mean that the tallest glyph will be 15px tall too. That depends on the font. This is somewhat analogous to normal, the initial value of line-height, which is defined as

Tells user agents to set the used value to a "reasonable" value based
on the font of the element[...]. We recommend a used value for
'normal' between 1.0 to 1.2.

That means that, if you use font-size: 15px, a "reasonable" line-height would be between 15px and 18px. In the "Verdana" font, Firefox thinks the best is 18px; in the "sans-serif", it uses 17px.

`padding` and `border` for inline elements being shown

The vertical padding, border and margin of an inline, non-replaced box start at the top and bottom of the content area, and has nothing to do with the 'line-height'. But only the 'line-height' is used when calculating the height of the line box.

https://www.w3.org/TR/CSS22/visudet.html#inline-non-replaced

padding, margin and border exists but have no influence on the calculation of the line box height. Margin cannot be seen unlike padding border but it does exist. You can notice it when you inspect the element.

Sample Image



Related Topics



Leave a reply



Submit