Recently dealt with a font icon that was not vertically centered in the container. I thought I was just writing CSS incorrectly, but it’s not that simple. After a lot of twists and turns, it turns out that it was a small detail that made a big hole. In the whole process of dealing with the problem, on the one hand, reviewed the relevant CSS basic knowledge; On the other hand, the reasoning method for the cause of the problem also gave me some new enlightenment, so I hereby record it.

The cause of

My colleague Xiao W asked me about a style problem: on the page he wrote, a font icon that should have been vertically centered changed to align with the top of the container. I don’t know where the CSS was written incorrectly, as shown in the picture (as the scene of the accident no longer exists, here is the scene of simulated restoration) :

<div class='wrapper'>
  <div class='inner'>
    <i class="far fa-check-circle"></i>
  </div>
</div>
Copy the code

CSS is as follows:

.outer {
  height: 60px;
  line-height: 60px;
  text-align: center;
  color: white;
  background-color: gray;
}

.inner {
  display: inline-block;
  font-size: 26px;
  line-height: 1;
}
Copy the code

Analysis of the

As you can see, the HTML structure is very simple, divided into three parts: outer, inner, inner, and the font icon itself. For the outer container, setting height to 60px is the classic vertical center method. However, the result is not centered. What went wrong? So first from the vertical center principle to analyze it.

Center it vertically with line-height

We often say, “Make height equal to line-height to achieve vertical center.” In fact, this statement itself, there are many problems. First of all, for a container and an inline element, there is no need to set height and line-height at the same time. Just set line-height to the container and it will be “vertically centered”, as shown below:

<div class='wrapper'>
  <span class='text'>Chinese text</span>
</div>
Copy the code
.wrapper {
  margin-bottom: 20px;
  line-height: 100px;
  color: white;
  background-color: gray;
  text-align: center;
}
Copy the code

You don’t need to set height to make sense, because line-height can also spread the container height, and the height is auto, which automatically calculates the value of line-height. The reason for the expression “make height equal line-height” is that the original practice was based on containers with fixed height. To center the text vertically, set the container’s line-height equal height. The problem is that the text is not really “vertically centered”. Instead, the “content area” of the text is centered. If you give the text a background color, you can see its content area:



display: inline-block

<div class='wrapper'>
  <span class='cube'></span>
</div>
Copy the code
.wrapper {
  margin-bottom: 20px;
  line-height: 100px;
  color: white;
  background-color: gray;
  text-align: center;
}

.cube {
  display: inline-block;
  width: 50px;
  height: 50px;
  background-color: white;
}
Copy the code

Set the vertical – align

For display: inline-block elements, to center them vertically, we usually add vertical-align: middle to center them vertically, as shown:

.wrapper {
  margin-bottom: 20px;
  line-height: 100px;
  color: white;
  background-color: gray;
  text-align: center;
}

.cube {
  display: inline-block;
  width: 50px;
  height: 50px;
  background-color: white;
  vertical-align: middle;
}
Copy the code

How does this work? Refer to the W3C definition of vertical-align when set to middle:

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

The vertical-align: middle element will align with the baseline font plus half of x-height, which is the median height of the lowercase x.



vertical-align
vertical-align: baseline



vertical-align: baseline

Align the baseline of the box with the baseline of the parent box. If the box does not have a baseline, align the bottom margin edge with the parent’s baseline.

So, the bottom of the element block, aligned with the baseline, is the line where the letter X is by default:

Try to repair

Display: inline-block = display: inline-block = display: inline-block = display: inline-block = display: inline-block

.wrapper {
  height: 60px;
  line-height: 60px;
  text-align: center;
  color: white;
  background-color: gray;
}

.inner {
  display: inline-block;
  font-size: 26px;
  line-height: 1;
  vertical-align: middle;
}
Copy the code

It didn’t work. Is it because there is only one font icon and no reference point? With this in mind, try adding a character next to the font icon as follows:





The minimum height consists of a minimum height above the baseline and a minimum depth below it, exactly as if each line box starts with a zero-width inline box with the element’s font and line height properties. We call that imaginary box a “strut.” (The name is inspired by TeX.).

And in the vertical-align paragraph:

The following values only have meaning with respect to a parent inline element, or to the strut of a parent block container element.

In short, when there is only one character, the browser will set a 0 – width hidden character in front of the text as a reference for alignment. So you don’t have to write a character to align it. Now, I’m messed up…

DOCTYPE trap

After you’ve calmed down, continue your analysis. It turns out that the HTML structure and CSS are exactly the same on different pages, but why are the actual styles different? According to the above theoretical analysis, it is found that there is no middle reason, probably because the browser does not provide such a strut, as a reference. This, however, does not conform to the specification defined by w3c. When I thought of this, I suddenly realized what was going on. After comparing the pages, I found only one difference:









<! DOCTYPE html>

conclusion

First of all, for vertical center problems, line-height is not always possible. This needs to be analyzed on a case-by-case basis, based on the basic w3c definition. Therefore, basic concepts should not only stay at the stage of being able to use them, but also need to be thoroughly read and understood. Secondly, for troubleshooting problems, in addition to combining theoretical basis, it is a good way to try to do comparison. Through comparison, step by step to eliminate irrelevant reasons, finally can dig out the problem; Finally, in the process of investigation, we must not preset conditions without evidence. Because in this case, one of the reasons for the long struggle is that the standard of the page itself is not considered, and the time spent trying to figure out how to use it is still unknown. It wasn’t until later, when we eliminated it step by step, that we got to the final cause.