I thought I knew my way around CSS, but I needed to explain something to someone just now and I found I couldn't.
My question basically boils down to: why is vertical-align:baseline
ignored when there are other alignments in the same line?
Example: if the second span has vertical-align:bottom
, the first span's vertical alignment is ignored if it is baseline
; it behaves as if it has bottom
too.
span:first-child {vertical-align:baseline}
span:last-child {font-size:3em; vertical-align:bottom;}
<p>
<span>one</span> <span>two</span>
</p>
While if all the spans have a vertical-align other than baseline
, or, if they are all baseline
, then they behave as expected.
span:first-child {vertical-align:top}
span:last-child {font-size:3em; vertical-align:bottom;}
<p>
<span>one</span> <span>two</span>
</p>
span:first-child {vertical-align:baseline}
span:last-child {font-size:3em; vertical-align:baseline;}
<p>
<span>one</span> <span>two</span>
</p>
If this is normal behaviour, then why isn't it described anywhere? I haven't found any source that says baseline and top/bottom interfere with each other in such a way.
Best Answer
Vertical-Align
vertical-align
is used to align inline-level elements. These are elements, whosedisplay
property evaluates to:inline
inline-block
inline-table
(not considered in this answer)Inline-level elements are laid out next to each other in lines. Once there are more elements than fit into the current line, a new line is created beneath it. All these lines have a so-called line box, which encloses all the content of its line. Differently sized content means line boxes of different height.
In the following illustration the top and bottom of line boxes are indicated by red lines.
Inside these line boxes the property
vertical-align
is responsible for aligning the individual elements.Baseline
The most important reference point to align vertically is the baseline of the involved elements. In some cases the top and bottom edge of the element’s enclosing box becomes important, too.
Inline elements
The top and bottom edge of the line height is indicated by red lines, the height of the font by green lines and the baseline by a blue line.
On the left, the text has a line height set to the same height as the font-size. The green and red line collapsed to one line on each side.
In the middle, the line height is twice as large as the font-size.
On the right, the line height is half as large as the font-size.
Note that the inline element’s outer edges (the red lines) does not matter, if the line height is smaller than the height of the font.
Inline-Block Element
From left to right you see:
an
inline-block
element with in-flow contentan
inline-block
element with in-flow content andoverflow: hidden
an
inline-block
element with no in-flow content (but the content area has a height)The boundaries of the margin is indicated by red lines, the border is yellow, the padding green and the content area blue. The baseline of each
inline-block
element is shown as a blue line.The
inline-block
element’s baseline depends on whether the element has in-flow content. In case of:in-flow content the baseline of the
inline-block
element is the baseline of the last content element in normal flow (example on the left)in-flow content but an
overflow
property evaluating to something other than visible, the baseline is the bottom edge of the margin-box (example in the middle)no in-flow content the baseline is, again, the bottom edge of the margin-box (example on the right)
Line box
This is probably the most confusing part, when working with
vertical-align
. It means, the baseline is placed where ever it needs to be to fulfil all other conditions likevertical-align
and minimizing the line box’s height. It is a free parameter in the equation.Since the line box’s baseline is invisible, it may not immediately be obvious where it is. But, you can make it visible very easily. Just add a character at the beginning of the line in questions, like the "x" in the figure. If this character is not aligned in any way, it will sit on the baseline by default.
Around its baseline the line box has what we might call its text box (green lines in the figure). The text box can simply be thought of as an inline element inside the line box without any alignment. Its height is equal to the
font-size
of its parent element. Therefore, the text box only just encloses the unformatted text of the line box. Since this text box is tied to the baseline, it moves when the baseline moves.Snippet
If you want to do some experiment with various
vertical-align
andfont-size
here you have a snippet where you can try it out. Is also available in JSFiddle.This snippet is made by Duannx.
Source: Please note that this is an extract of Vertical-Align: All You Need To Know written by Christopher Aue.