lonelyass lonelyass - 2 months ago 14
HTML Question

Inline and inline-block work differently with vertical-align

I read this great article on vertical-align and came up with a very confusing example:



html {
font-size: 100px;
}

body {
margin: 0;
}

div {
display: inline-block;
vertical-align: middle;
}

<html>
<body>
x
<div>
x
<div>
x
<div>
x
<div>
x
<div>
x
</div>
</div>
</div>
</div>
</div>
</body>
</html>





I expected to see a ladder, but I did not expect that steps of this ladder will have different heights. Can someone explain what determines it? I noticed that when I change the display to "inline", all steps have the same height.

Answer

vertical-align: middle does exactly this:

Align the vertical midpoint of the box with the baseline of the parent box plus half the x-height of the parent.

enter image description here

The red line is the baseline of the parent box plus half the x-height of the parent

The different heights of the ladder are due to the fact that the midpoint of the x is moved closer to the midpoint of the box due to the space caused by inner nesting.

For example,

  1. Suppose that the line-height is 100px, the height of the "x" is 40px, and the baseline is at 20px above the bottom. So the line has 40px empty at the top, 40px for the x, and 20px empty at the bottom. The middle of the "x" is at 20px + 20px/2 = 40px above the bottom.

  2. Then, you align that box to the middle, and nest it inside another box with a "x". The middle of the nested box will be aligned with the middle of the "x" of the outer box. But half height of the nested box occupies 100px/2 = 50px, while there are only 40px below the midpoint of the x in the outer box. Therefore, the outer box grows by 10px to prevent the nested box from overflowing.

    So the outer box will have 40px empty at the top, 40px for the outer "x", and 30px empty at the bottom (10px of which due to the alignment of the inner box). The outer box will be 110px tall.

  3. Then, you nest the previously outer box inside another box. Half height of the nested box occupies 110px/2 = 55px, while there are only 40px below the midpoint of the "x" in the outer box. Therefore, the outer box grows by 15px.

    So the outer box will have 40px empty at the top, 40px for the outer "x", and 35px empty at the bottom (15px of which due to the alignment of the inner box). The outer box will be 115px tall.

  4. Then, you nest the previously outer box inside another box. Half height of the nested box occupies 115px/2 = 57.5px, while there are only 40px below the midpoint of the "x" in the outer box. Therefore, the outer box grows by 17.5px.

    So the outer box will have 40px empty at the top, 40px for the outer "x", and 37.5px empty at the bottom (17.5px of which due to the alignment of the inner box). The outer box will be 117.5px tall.

  5. And so on.

This does not happen when you use display: inline because

for inline non-replaced elements, the box used for alignment is the box whose height is the line-height (containing the box's glyphs and the half-leading on each side, see above). For all other elements, the box used for alignment is the margin box.

Comments