Abstract
Each HTML element (acts as container) is actually a stack of line-boxes, the contained elements is stuffed into each line-box. In this article, we try to find out what makes the height of each line-box, and how each element is aligned in line-box
keywords: strut, line box, content area, vertical align
Content Area
Let’s start from the start point, there’s only one element in line-box:
See the Pen xPvMdJ by 谢超 (@xiechao06) on CodePen.
Let checkout it out carefully, here we set font-size: 100px
, but is this span
element has a height of 100px? No!!!, it has a height of 164px. The reason
is elaborated in this great article https://iamvdo.me/en/blog/css-font-metrics-line-height-and-vertical-align.
Here we only remember the facts:
font-size
is relative to height of content area, but IS NOT the height of content area.- ascender plus descender is the height of the content area.
- content area holds the text, whilst property line-height contributes to the height of line-box,
and we call this height the local line-height of the element, and it makes the local line-box of the element. and content area is always aligned center in local line-box.
note!!! content area is not the line box’s height, but as we have only element, we could consider these 2 value has the same value for now
Let’s go a little further, what is line-box’s height? 164px, and what is span‘s line height property? a special value: normal
, which is also the default value. We could guess what does normal means: a value computed by browser, that could just accomodate (sometimes, a little bigger than) the content area.
Now we comes to a problem: what is a proper value of line height?
As we said, line height contributes the height of line-box (only for inline elements, plus vertical-align). and usually, it is set to the times of font-size, not the height of content area. so if the line-height is too small, two line-box may collapse. Here we got:
See the Pen XzvOyB by 谢超 (@xiechao06) on CodePen.
As we said, padding won’t affect the height of line-box either.
See the Pen xPvMeB by 谢超 (@xiechao06) on CodePen.
the real computation of height of line box and vertical-align
Start from this example:
See the Pen rYXRaQ by 谢超 (@xiechao06) on CodePen.
You may wonder why there are 2 spacings below and up the span element, that is due to strut - an imagined, invisible and zero-width character inserted into container automatically. if there’s any elements in this container. here we give a more extrem example:
See the Pen xPvBwN by 谢超 (@xiechao06) on CodePen.
Even the contained element has no size, strut still works. And we could also comes to the conclusion: a line box has a height bigger than the strut’s content area, With the help of strut, we could enter the dangerous zone of vertical-align.
See the Pen WXVmGd by 谢超 (@xiechao06) on CodePen.
Let’s analysis this snippet:
The first element, spacing maker
, align its baseline to strut’s baseline, then browser found its line height is 4, so the line box’s height is expanded to 4 * 18px = 72px.
here, we could see where line-box’s baseline is clearly.
Then comes middle, align the middle point of content area to the line-box’s baseline plus half of x-height.
Then come text-top, align the top of content area to the strut‘s content area.
Then come text-bottom, align the bottom of content area to the strut‘s content area.
Then come top, align the top of content area to the top of line-box.
Then come bottom, align the top of content area to the bottom of line-box.
As we could see, find out where is strut’s content area (top, bottom, baseline) and line-box is key to understand vertical-align. Now let’s analyse some more examples:
See the Pen WXVBqE by 谢超 (@xiechao06) on CodePen.
Without the leading x, you may be very confused why the last span
goes up/down. But with it, you could see the relation between strut and line-box.
Now we comes to the inline-box elements. property height but line-height contributes to the height of line-box, let’s check an example.
See the Pen VroJeL by 谢超 (@xiechao06) on CodePen.
Let’s analysis what contributes to an inline-box element has a size and position:
- inline-box element’s baseline is determined by its in-flow text.
- box instead of line-box contributes to the height of line-box, and its top/bottom edge is used to align vertically.
- line-height determins the relative position of box and local line-box. or line-box’s top edge reachs to the top edge of box.
namely, for an inline-box element, align it vertically at first (top, bottom or baseline), then draw the box, then draw the local line-box. Here is an example of vertical-align: top
.
Now, let’s answer a common problem: what to do if we want align text vertically in the box of inline-block element? the answer is easy: make local line-box the same height of box. Since text is aligned in the middle automatically in local line-box.
See the Pen xpKRvM by 谢超 (@xiechao06) on CodePen.
more about inline-box’s baseline please refer to http://christopheraue.net/2014/03/05/vertical-align/.
Summary
To understand the inline-elements’ formatting problem, ask yourself the following questions:
- what is strut’s height, where its baseline is?
- for each contained element, the size of its local line-box/box, and where its baseling is?
- consider the baseline as fixed, where is the top/bottom edge of line-box?
References
https://iamvdo.me/en/blog/css-font-metrics-line-height-and-vertical-align
http://christopheraue.net/2014/03/05/vertical-align/