The introduction

Vertical-align is commonly used to align adjacent text and inline elements, such as the common alignment of an icon with adjacent text. However, when you don’t know how it works, it often drives you crazy, so we tried to solve the mystery of this rule once and found a [great article][1] while searching, which is a translation, to summarize this attribute

How does vertical-align work on inline elements in a line box

Vertical-align is used to align inline cascade elements, that is, elements whose display values are inline, inline-block, or inline-table (this is usually not considered). An inline element is a basic tag that contains text, such as span. Inline-blocks, as the name suggests, are block-level elements within a line that can set the width, height, spacing border, and so on.

Inline cascaded elements are arranged next to each other as rows, and as soon as there are more inline cascaded elements than the current row can hold, a new row is created below them. That’s what we always sayline box(line box), the line box contains all the content in its line. Different sizes of content mean that line boxes have different heights. The figure below shows the top and bottom of three row boxes in red line.

The line box defines the area occupied by the content, and vertical-align aligns the elements in the line box. So the question is, what lines are these elements aligned with?

Bottoms What you need to know about baselines, tops, bottoms

The most critical reference lines for vertical alignment are the elements’ baseline baselines. In some cases, elements that contain the top line of the box, tops, and the bottom line, bottoms, also become important. Here are the baselines, tops and bottoms for each type of element.

The inline elements

As shown, there are three lines of text with different lines. The red line represents the top and bottom of the line; The green line represents the font height of the text. It should be noted that the actual height occupied by the text content area is not strictly equal to the font height, but is determined by font-size and font-family together. In general, it is greater than the font height; in special case, the actual content area height is equal to the font height. But this difference is generally not a big deal, we’ll just assume that the height of the content area is represented by the height of the font; The blue line represents the baseline, which can be understood as the bottom edge of the letter X, which is about 1/2 the height of the letter X lower than the center of the font height.

The line height on the left is set to the same height as the font, so the red and green lines overlap. The line height of the middle figure is set to twice the font height, and the line spacing is divided into two parts equal to one font height, that is, half the font height upward and downward relative to the green line. Set the line height on the right to half the font height, i.e. one quarter of the font height down and up relative to the green line.

The inline – block element

From left to right, contains in-flow content (non-floating, An inline-block element containing in-flow content in a stream sets overflow:hidden, and an inline-block element with no stream content but height. The red line shows the margin of the inline-block element. In the figure, yellow is border, light green is padding, and light blue is content. The blue line represents the baseline of the inline-block element.

The outer edges of the inline-block element are the top and bottom edges of the margin-box, which are the red lines in the figure. The rule judgment of baseline is complicated, which can be simply written as: if the contents of inline elements are not included or the overflow attribute is not visible, the baseline is the bottom edge line, that is, the bottom edge of margin-box. Otherwise the baseline is the baseline for the last inline element in the row.

Line box line box

The above image clearly shows the structure of the line box with several lines. The green lines represent the top and bottom lines of the text box in the line box. The text area is also highlighted with a gray background.

The top line of the line box is aligned with the outer red line of the highest element in it, and the bottom line is aligned with the outer red line of the lowest element in it. Again, the outer edge lines are the ones discussed above, inline elements are the top and bottom lines of line-height, and the outer edge lines of inline-block elements are the top and bottom lines of margin-box. Therefore, the line box has the property of large value, the highest to determine the final height.

The baseline of a line box is not precisely defined in the draft:

CSS 2.1 does not define the position of the line box’s baseline. — the W3C Specs

This is probably the most confusing part, because what he means is that the baseline of the line frame is at a position that simultaneously satisfies all other vertical-aligns and minimizes the height of the line frame. This is still very abstract, but one way to make it concrete is to add an X character to the front of the line box as shown in the figure, which aligns the baseline baseline.

The green line around this baseline, the word box, can be interpreted as an inline element in the line box without any alignment, whose height is equal to the height of the font (as mentioned earlier, regardless of the font). The draft calls the invisible box we simulate here with character X a strut, and Zhang Xinxu calls it a ghost blank node in his blog. To summarize, the line box is where Vertial-align works. It includes a base line, a word box, a top line, and a bottom line. Each inline element also has its own baseline, top line, and bottom line.

Vertical-align baselines, tops, bottoms

The various forms of alignment are shown in the figure above.

  • baseline: The baseline of the inline element is at the line box baseline.
  • sub: The baseline position of the inline element is lower than that of the line box.
  • super: The baseline position of the inline element is higher than that of the line box.
  • <percentage>: The value of the inline element’s baseline movement relative to the line box baseline corresponding to the line height percentage.
  • <length>: The inline element’s baseline moves by an absolute value relative to the line-box baseline.
  • middleCentering means that the top line of the inline element and the middle line of the bottom line are offset by one half of the baseline of the line boxx-height, can be approximately understood as charactersxIntermediate crossing point.

  • text-top: Aligns the top line of the inline element with the top line of the word box of the line box.
  • text-bottom: Aligns the inline element bottom line with the word bottom line of the line box.

  • top: Aligns the top line of the inline element with the top line of the line box.
  • bottom: Aligns the inline element bottom line with the line box bottom line.

Case study: Why does vertical-align behave this way

Image and text alignment is one of the most common scenarios for front-end developers, and while it’s now common to use font ICONS or components that don’t need to be considered in most cases, it’s important to understand the basics when writing your own. Let’s look at this example.

Center icon

An icon has a line of text next to it. If you center the text with the icon, most people will use vertical-align: middle for the icon, but you will notice that it is not really centered:

The contrast between the two sides of the image is obvious, with the text on the left slightly up and the text on the right perfectly centered. The code on both sides looks like this:

<! -- left mark-up --> <span class="icon middle"></span> Centered? <! -- right mark-up --> <span class="icon middle"></span> <span class="middle">Centered! </span> <style type="text/css"> .icon { display: inline-block; /* size, color, etc. */ } .middle { vertical-align: middle; } </style>Copy the code

Why is this?

Draw an auxiliary line to see:

Obviously, the text on the left is aligned to the baseline by default, and splitting the text with ascender in the middle of the X would be a bit higher.

The image on the right wraps the text with a SPAN tag and then uses middle for the entire text content area so that the base line is slightly lower than the line line so that it is centered with the icon.

The movement of the baseline position of the line box

As mentioned earlier, the position of the line frame baseline is affected by all the elements in the row, and most alignment is related to the line frame baseline, so if the line frame baseline changes, the layout will change.

For example:

  • If there is a tall inline element that is higher than the height of the previous line box, see how the space occupied by the line box changestext-botttomAlign, righttext-topAlignment. You can see the position of the line frame baseline and top line, bottom line.

<! -- left mark-up --> <span class="tall-box text-bottom"></span> <span class="short-box"></span> <! -- right mark-up --> <span class="tall-box text-top"></span> <span class="short-box"></span> <style type="text/css"> .tall-box, .short-box { display: inline-block; /* size, color, etc. */ } .text-bottom { vertical-align: text-bottom; } .text-top { vertical-align: text-top; } </style>Copy the code

The gap below the inline element

Let’s think about a common scenario:

<ul>
  <li class="box"></li>
  <li class="box"></li>
  <li class="box"></li>
</ul>

<style type="text/css">
  .box { display: inline-block;
         /* size, color, etc. */ }
</style>
Copy the code

There is always a descender below the inline element because of the ghost space. The inline block’s base line is now descender under the frame after the base line is aligned with the frame’s base line. To avoid this problem, change the frame’s base line position, such as top and Middle.

<ul>
  <li class="box middle"></li>
  <li class="box middle"></li>
  <li class="box middle"></li>
</ul>

<style type="text/css">
  .box    { display: inline-block;
            /* size, color, etc. */ }

  .middle { vertical-align: middle; }
</style>
Copy the code

conclusion

There are only two things you need to know about alignment in the future:

  • Where is the baseline, top line and bottom line of the line frame?
  • Where is the baseline, top line, and bottom line of an inline element?