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">•</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">•</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
.
— 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.
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.
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.
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.
§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:
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
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.
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:
Then, as other answers explain, a way to solve the problem is reducing .smaller
's line-height
:
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.
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">•</span>mal
</div>
<div class="why-not-sixty-px">
multiline multiline multiline multiline multiline multiline <span class="smaller">•</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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With