How to determine height of content-box of a block and inline element

For block elements its quite easy but you need to distinguish between two different cases. When we have an IFC (inline formatting context) or BFC (block formatting context). From the specification you can read

If ‘height’ is ‘auto’, the height depends on whether the element has any block-level children and whether it has padding or borders:

The element’s height is the distance from its top content edge to the first applicable of the following:

  1. the bottom edge of the last line box, if the box establishes a inline formatting context with one or more lines
  2. the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child’s bottom margin does not collapse with the element’s bottom margin
  3. the bottom border edge of the last in-flow child whose top margin doesn’t collapse with the element’s bottom margin
  4. zero, otherwise

Only children in the normal flow are taken into account (i.e., floating boxes and absolutely positioned boxes are ignored, and relatively positioned boxes are considered without their offset)

If we consider an IFC then the line boxes will define our height exactly like your examples where in the div and p you have one line box defined by the line-height.

If we consider a BFC then the (2) and (3) apply. Here, you can see it as a recursive definition because having a BFC means we have other blocks inside and those blocks will follow the same rules (either BFC or IFC and so on). In addition, we consider the margin collapsing rules to get the final height.

If the block is empty then it’s zero.

Of course, this consider the case of height:auto. If you explicitely set a height then it’s trivial.


For inline elements you can 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.)

Here is a bit tricky but the rule is simple: you cannot control or set the height of the content area. Only the font properties you will be using will define the final height.

You should also note that the content area is different from the line box.

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.

<span style="background-color: aquamarine; font-size: 16px; line-height: 2em;">Is line-height same as height of span tag?</span>
<br>
<span style="background-color: aquamarine; font-size: 16px; line-height: 4em;">Is line-height same as height of span tag?</span>
<br>
<span style="background-color: aquamarine; font-size: 16px; line-height: 8em;">Is line-height same as height of span tag?</span>

If you increase the line-height you will clearly notice that the background won’t cover a bigger area but only the line box will be bigger

Some related question to get more details and understand the difference between line box and content area:

Can specific text character change the line height?

Box Model for Inline Elements

Why is there space between line boxes, not due to half leading?


So line-height will indeed define the height of block element and not inline element since the block element height will depend on the height of the line boxes and the height of line boxes are defined with line-height1

Here is an example to show a block element having its height defined by the line box and the content area of the inline element inside will oveflow because they play no role in defining the line boxes:

p {
  margin:50px;
  font-size:35px;
  border:1px solid red;
  line-height:0;
}

span {
  background:green;
  line-height:10px;
}
<p>
 <span>some text here and there</span>
</p>

<p>
 <span style="font-family:cursive">some text here and there</span>
</p>

In both examples, we have a height equal to 12px for the p (10px of line-height + 2px of border) and our inline element is having a different height in each case because the font is not the same.


1: We should note that in practise it can be more complex and the value of line-height alone isn’t enough.

If we read the specficiation we can see that:

On a block container element whose content is composed of inline-level elements, line-height specifies the minimal height of line boxes within the element.

Then

On a non-replaced inline element, line-height specifies the height that is used in the calculation of the line box height.

That’s why in the last example I made the line-height of the block element to be 0 so only the line-height of the inline elements inside will define the final height of the linebox

Even the vertical alignment play a role here because if we have multiple elements not aligned the same way and with different line-height, finding the result will be more complex:

p {
  margin:50px;
  font-size:35px;
  border:1px solid red;
  line-height:0;
}

span {
  background:green;
  line-height:1;
}
<p>
 <span>AB</span> <span >AB</span>
</p>


<p>
 <span>AB</span> <span style="vertical-align:super">AB</span>
</p>

To find the height of a linebox you need to consider 3 factors:

  1. The line-height of the block container (the IFC)
  2. The line-height of the inline elements inside
  3. the vertical alignment of inline elements

Let’s not forget that line-height is inherited so if we don’t set it explicitely we need to either consider the value of the parent element or the default one.

Leave a Comment