Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I mix vertically-centered elements with different font sizes and retain consistent line height?

Tags:

When you mix font-sizes of elements with vertical-align: middle inside of a container, the container's height can be larger than the line-height or height of either individual element. Here is a fiddle:

body {
  line-height: 20px;
  font-size: 14px;
}
.smaller {
  font-size: 0.9em;
  vertical-align: middle;
}
<div class="body">
  <div class="why-not-twenty-px">
    containing div has height <span class="smaller">&bull;</span> of 21px, not 20px
  </div>
  <div class="why-not-sixty-px">
    containing div has height of 61 px, not 60px multiline multiline multiline multiline multiline multiline <span class="smaller">&bull;</span> multiline multiline multiline multiline multiline multiline multiline multiline multiline multiline multiline multiline multiline multiline multiline multiline multiline multiline multiline multiline multiline
  </div>
</div>

In this example, the two containing divs are 21px and 61px instead of 20px and 60px.

How can I retain a container height that is a multiple of the line-height when mixing in an element like .smaller? .smaller must be vertically centered on the line. Ideally, any solution would only involve CSS changes to .smaller.

like image 511
Jeremy Kauffman Avatar asked Dec 24 '14 14:12

Jeremy Kauffman


People also ask

Does line height affect font size?

— font size. Smaller type tends to need more line height, not less. A generous line height helps the eye to recognize small word shapes more easily, and it encourages horizontal motion when the eye gets tired of reading small text. Left: A line height set at 150% is a bit too tight on an iPhone.

How do I center text in line height in CSS?

Use line-height for vertical centering with a fixed height To vertically center a single line of text or an icon within its container, we can use the line-height property. This property controls the height of a line in a run of text and adds an equal amount of space above and below the line-box of inline elements.

How do you determine the height of a font line?

For the optimal readability and accessibility, you should go with140 – 180% line height (this is the space around a line of text). This means if your font size is 16pt, your line height should be at least 16 x 1.4 = 22.4pt (140%), or 16 x1. 8= 28.8pt (180%) maximum value.

How do you increase line height in CSS?

The line-height CSS property sets the height of a line box. It's commonly used to set the distance between lines of text. On block-level elements, it specifies the minimum height of line boxes within the element. On non-replaced inline elements, it specifies the height that is used to calculate line box height.


1 Answers

§10.8 explains how the height of the line boxes is calculated:

As described in the section on inline formatting contexts, user agents flow inline-level boxes into a vertical stack of line boxes. The height of a line box is determined as follows:

  1. The height of each inline-level box in the line box is calculated. [...] For inline boxes, this is their 'line-height'

    Since .smaller inherits line-height: 20px and is an inline box (i.e. non-replaced with display: inline), its height is 20px

  2. The inline-level boxes are aligned vertically according to their 'vertical-align' property.

    .smaller has vertical-align: middle, which means

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

  3. The line box height is the distance between the uppermost box top and the lowermost box bottom.

So both the text and .smaller have a height of 20px, but they have different alignment. Therefore, the line box grows:

enter image description here

Then, as other answers explain, a way to solve the problem is reducing .smaller's line-height:

enter image description here

However, there is an alternative solution, without modifying line-height: negative margins can be added to prevent .smaller from increasing the height of the line box.

As quoted above, the height of an inline box is its line-height, so to make the margins work, display: inline-block is also needed:

The height of each inline-level box in the line box is calculated. For [...] inline-block elements [...] this is the height of their margin box.

Note this solution won't break the alignment, because since .smaller has vartical-align: middle, if we use the same amount in margin-top and margin-bottom, it will remain centered.

enter image description here

To summarize, you can use this code:

.smaller {
    vertical-align: middle;
    display: inline-block;
    margin: -1em 0;
}

body {
  line-height: 20px;
  font-size: 14px;
}
.smaller {
  font-size: 0.9em;
  vertical-align: middle;
  display: inline-block;
  margin: -1em 0;
}
<div class="body">
  <div class="why-not-twenty-px">
    nor<span class="smaller">&bull;</span>mal
  </div>
  <div class="why-not-sixty-px">
    multiline multiline multiline multiline multiline multiline <span class="smaller">&bull;</span> multiline multiline multiline multiline multiline multiline multiline multiline multiline multiline multiline multiline multiline multiline multiline multiline
    multiline multiline multiline multiline multiline multiline multiline multiline multiline multiline
  </div>
</div>
like image 149
Oriol Avatar answered Oct 17 '22 06:10

Oriol