preface

Line-height and vertical-align are commonly used in CSS development, but they are not easy to use. For example, in the use of some special fonts are often mixed or text alignment ICONS, you may find that no matter which method is used, it always feels like text or images are offset up or down by a few pixels. They have to be shifted specifically; Or maybe you can’t use vertical-align with middile, etc. Why do these things happen? Let’s talk about it in more detail.

Several related concepts

Let’s take a look at some concepts related to line-height and vertical-align.

The baseline

In the picture, the lines from top to bottom are top line, mean line, middle line, baseline, and bottom line, just like the four lines and three grids when we just learn English letters. We know that vertical-align attributes include top, middle, baseline, and bottom, which are associated with these lines.

Baselines are the concept of Western font design and typography, derived from the position where the bottom of the body of the Western letter (the bottom of the letter E) is aligned.

For Chinese fonts, there is no such thing as a baseline in the design itself, each character is in a square box. However, when displayed on the computer, the concept of Western fonts is also used to some extent. Generally speaking, the bottom of the Chinese font is between the baseline and the bottom line, and the top is a little below the top line.

Line height, line spacing, half-line spacing, and x-height

  • Line height: Also known as line-height, refers to the vertical distance between the baseline of the text line. The vertical distance between any two of the same colors is also the row height.

  • Line spacing: Refers to the vertical distance between the bottom line of a line and the top line of the next line, that is, the vertical distance between the first pink line and the second green line.

  • Half-space: Half of the line space. Half line spacing = (line height – type) / 2. Margin-top in CSS does not start at the top line of text, but at the top half of the line. Similarly, margin-bottom starts below the bottom half of the line.

  • Height: The distance between the baseline baseline and the mainline mean line.

font-size

In front end development we will use font size to set the text size. If we set the font to 12px, it means the distance between the top line and the bottom line is 12px.

Four types of “Boxes” in CSS

There are four types of inline boxes in the CSS: containing boxes, line boxes, inline boxes, and Content area.

  • Containing box (containing boxEach block countscontaining boxThat it containsline boxes.line boxesThe height of the vertical stack formedcontaining boxThe height of the.
  • Line box (line boxes) : Each line rendered by the contents of the block can be regarded as a line box, or each line is a line box.line boxesThe number of lines is determined by the width and content of the block, without limiting the height. There are multiple inline boxes in a row, one by oneinline boxesMake up theline boxes, a line box contains the highest and lowest point of a line inside a box. It has the highest height in the rowline-heightDecision.
  • Inline box (inline boxes) : not displayed in blocks, but side by side on a lineboxes, such asspan,a,emTags and anonymityinline boxes(i.e. contains naked text without labels).
  • Line content area (content area) :content areaIt’s an invisible box around text.content areaWith the size of thefont-sizeSize depends. After selecting the text, the background color is the content area (orange below).
<! -- HTML code -->
<div>Here's a DIV that contains separate text,<span>Span tags</span>
 <em>Em label</em>And so on, and some other words.</div>
Copy the code

line-height

Line-height is the distance between the baselines of the text lines. Line-height actually affects only the inline elements and other inline content, not block-level elements directly. It is also possible to set line-height for a block-level element, but only when applied to the inline content of a block-level element. Declaring line-height on a block-level element sets a minimum line-box height for the block-level element’s content.

The line – height value

value describe
normal The default value. Depending on the browser’s parsing, the line height is generally 1.2. The children are evaluated separately
number Sets a number that is multiplied by the current font size to set the line spacing, i.e. number is a multiple of the current font size. In most cases, this is the settingline-heighttheRecommended approach, does not produce uncertain results on inheritance
length Set fixed line spacing withfont-sizeIrrelevant, not withfont-sizeScaling is inherited by subsequent elements
% Percentage line spacing based on current font size
inherit Inherits the value of the line-height attribute from the parent element

Line-height inheritance problem

Line-height is inheritable. The different row height units of the parent element affect the inheritance of the child elements. Such as:

  • The row height of the parent element is15pxWhen, the child element directly inherits the fixed row height
  • The row height of the parent element is150%or1.5 emWill be based onThe parent elementthefont-sizeThe trip height is computed and then the child element inherits
  • The row height of the parent element is1.5When, according toChild elementsthefont-sizeDynamically compute the trip heights for child elements to inherit
// Some CSS code.px-line-height {
  line-height: 15px;
}

.em-line-height {
  line-height: 1.5 em;
}

.percent-line-height {
  line-height: 150%;
}

.nounits-line-height {
  line-height: 1.5;
}
Copy the code

Online demo > >

Line-height And line box height

To introduce line-height and line boxes, let’s talk about a common phenomenon. There is an empty

, which is 0 when height is not set. If the div is typed with a space or text, the div will have a height. So have you ever wondered why a div has a height when it has text inside it?

Some people may think it is: the text spread! Text takes up space and naturally spreads the div out. That’s what I thought at first, but in fact, digging deeper into the inline model, IT turns out that it’s not the text that expands the div’s height at all, it’s line-height! The proof is simple (here’s the test code) :

/ / CSS code.test1 {
  font-size: 20px;
  line-height: 0;
  border: 1px solid #ccc;
  background: #eee;
}

.test2 {
  font-size: 0;
  line-height: 20px;
  border: 1px solid #ccc;
  background: #eee;
}
Copy the code
<! -- HTML code -->
<div class="test1">Test 1</div>
<div class="test2">Test 2</div>
Copy the code

Online demo > >

How does line-height produce height? In the inline box model, there is an invisible line box whose job is to wrap each line. So the height of a div without height is a stack of the heights of line boxes.

vertical-align

The vertical-align attribute affects the vertical layout of an inline cascade element. This applies to elements whose display value is inline, inline-block, or table-cell.

The value of vertical – align

value describe
baseline The default. This element (baseline) is placed on the baseline of the parent element.
middle Appends the parent element to the middle (middle line) of the element and the baseline of the parent elementx-heightHalf aligned (approximately vertically centered)
top Align the top of the element with the top of the highest element in the row.
bottom Align the top of the element with the top of the lowest element in the row.
text-top Align the top of the element with the top of the parent element’s font (font is important).
text-bottom Align the bottom of the element with the bottom of the parent element’s font (font is important).
sub Vertically align the subscript of the text.
super Vertically align the superscript of the text.
length Aligns the element’s baseline to a given length above the parent element’s baseline. It could be negative.0pxIs equivalent tobaseline
% The given percentage that aligns the element’s baseline above the parent element’s baselineline-heightThe percentage of attributes, which can be negative.0%Is equivalent tobaseline
inherit Specifies that the value of the vertical-align attribute should be inherited from the parent element.

Note that all attribute values are relative to the parent element, except for top and bottom, which align the element vertically relative to the inline element. So, during development, we only need to focus on the current element and the parent; there is no direct influence between the two elements.

top

<! -- HTML code -->
<div class="block">
	<span class="child"></span>
	<span class="top">Child elements Aa</span>game
</div>
Copy the code
// Core CSS code.block {
  font-size: 50px;
}

.child {
  display: inline-block;
  width: 40px;
  height: 80px;
  margin-top: 20px;
}

.top {
  vertical-align: top;
}
Copy the code

Online demo > >

In the figure above, the “child element Aa” has vertical-align set to top, which is aligned with the top of the highest element in the current line box, which contains the margin value.

text-top

<! -- HTML code -->
<div class="block">
  <span class="child"></span>
  <span class="a">Child elements Aa</span>Child elements Bb<span class="c">Child elements Cc</span>
</div>
Copy the code
// Core CSS code.block {
  font-size: 50px;
}

.child {
  display: inline-block;
  width: 40px;
  height: 80px;
  margin-top: 20px;
}

.a {
  vertical-align: text-top;
  font-size: 30px;
}

.c {
  font-size: 80px;
}
Copy the code

Online demo > >

In the image above, the font of the parent element is 50px, so the font of the same child element Bb is 50px, so it can be considered aligned with the top of the child element Bb.

Bottom is different from text-bottom and top is different from text-top.

Several common phenomena and solutions

Let’s take a look at some of the phenomena associated with line-height and vertical-align in everyday development.

The gap below the picture

performance

First look at the code:

<div class="block">
  <img width="200" src="abc.png">
</div>
Copy the code
// Core CSS code.block {
  background: #eee;
}
Copy the code

Online demo > >

Take a look at the results:

Look carefully at the picture there is a gap of a distance, why does this gap appear?

Earlier in this article we learned that the default alignment of elements is by baseline baseline alignment; Browsers have default font sizes, and this gap comes from those two. If the parent element is given a larger size, the gap becomes larger. To make it easier to see, we add an anonymous inline box (i.e., naked text with no labels). The result is shown below.

How to remove this gap

  1. letvertical-alignFailure. Images default to inline cascaded elements, whilevertical-alignNot valid for block-level elements. So we just let the picturedisplayLevel ofblockIt’s ok;
  2. vertical-alignSay goodbye tobaseline. Set totop.bottomOr,middleEquivalent;
  3. willline-heightSet to sufficiently small or0. The gap height below is actually the computed line height of the text (line-height) bottom edge and lettersxDistance from baseline. Therefore, as long as the row height is small enough, the baselinebaselineIt will move up, and naturally, the picture will have the bottom of the container coming together;
  4. willfont-sizeSet to0.font-sizeIs indirectly controlled by the value ofline-height.font-sizeSet to0In essence, changeline-heightValue;
  5. willimgSet float or absolute position.

Vertical-align :middle Does not have absolute center

performance

Vertical-align :middle This attribute is used by most developers. Take a look at the following example:

<div class="block">
  <img width="200" src="abc.png">
  x
</div>
Copy the code
// Core CSS code.block {
  font-size: 100px;
  line-height: 250px
}

img {
  vertical-align: middle;
}
Copy the code

Online demo > >

In the figure above, the gray background is the parent element; The yellow line is the vertical center line of the parent element; The green line is the baseline of x, the parent element; The blue line is the vertical center line of the red image, and the red image has the middle alignment set. By definition, the blue line is aligned with the line at half the x-height above the green line, the center of the letter X. If absolutely centered, the yellow and blue lines should overlap perfectly.

Why does this happen? The main reason is that the text has the characteristics of sinking (that is, the vertical center point of the text sinks a little bit in the middle line of the text area, and the extent of sinking is different in different fonts), so the blue line cannot absolutely align with the yellow line. When the text size is small enough, we can ignore it. So as to achieve approximate center effect. But the bigger the text, the more obvious the impact.

How to solve

So how do we solve this problem? Here are two ideas (and, of course, there may be other, better ones) :

1. Use the align-items property in the Flex layout to center the child and parent elements on the vertical axis. The code is also relatively simple:

HTML code as above.

// Core CSS code.block {
  font-size: 100px;
  line-height: 250px;
  display: flex;
  align-items: center;
}
Copy the code

Online demo > >

2. The “X” (unlabeled, naked text) in the image can be affected by the inherited CSS property, so we can adjust it by other Settings so that the character center line and the character content center line are together, or in the same position. Font-size :0; mso-bidi-font-size :0; mso-bidi-font-size :0; mso-bidi-font-size :0; mso-bidi-font-size :0; mso-bidi-font-size :0; As follows:

<div class="block">
  <img width="200" src="abc.png">
  <span class="a">Child element x</span>
</div>
Copy the code
// Core CSS code.block {
  font-size: 0;
  line-height: 250px
}

img {
  vertical-align: middle;
}

.a {
  font-size: 100px;
  vertical-align: middle;
}
Copy the code

Online demo > >

conclusion

This article first explains some basic concepts related to text and the relationship between four kinds of inline boxes, as well as the basic attributes and common manifestations of line-height and vertical-align, and at the same time, makes a simple analysis of some common phenomena in practical applications, and provides ideas for solving such problems. The authors conclude:

  • line-heightandvertical-alignThey’re not very reliable
  • cssThe most difficult thing to tune is the style of the text

reference

  • MDN Web Docs line-height
  • MDN Web Docs vertical-align
  • Some in-depth understanding and application of CSS line height
  • Deep dive CSS: font metrics, line-height and vertical-align
  • CSS provides an in-depth understanding of vertical-align and line-height relationships