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
.
§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 (ie 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>
You can fix this by making the line-height
relative to the font-size
, instead of a fixed one.
body {
line-height: 1.4285;
font-size: 14px;
}
will fix the issue of the extra pixels on the containers.
Demo at http://jsfiddle.net/gaby/b5zgpktj/
To only affect the .smaller
element you can give it a line-height
of 1
.smaller
{
line-height:1;
font-size: 0.9em;
vertical-align:middle;
}
Put line-height: 100%
or line-height: 1
(preffered) on .smaller
element. Also, if you put vertical-align: top
or vertical-align: bottom
without changing line-height containers would be 20px and 60px.
By making line-height computed from actual font-size or ensuring element top/bottom is aligned with parent, height remains same (this assumes your child element always has smaller font-size than parent). Otherwise you inherit 20px fixed line-height which adds to parent total height when parent and child boxes are not aligned (this happens when font-size differs and vertical-align is anything than top/bottom, including middle
or default baseline
value).
body { line-height: 20px; font-size: 14px; } .smaller { font-size: 0.9em; line-height: 1 // or 100% 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>
Reference:
The container div is taking a height of 21px because the span.smaller element is having a line-height of 20px. The siblings of span element also have a line height of 20px. You need to understand that line-height property is used while calculating the vertical-align property. Now if you want to apply "vertical-align: middle" to the span.smaller change its line-height to something smaller than their siblings line-height ie 20px, or else it will try to center the span.smaller element with respect to its siblings. Since span.smaller line-height is also 20px it will cause the container to have more height.
For example
<div class="body">
<div class="why-not-twenty-px">
containing div has height
<span class="smaller"> •</span>
of 21px, not 20px
</div>
<div class="abcd">
<span>The same problem can </span>
<span style="vertical-align:middle;color:grey;"> be replicated </span>
<span> while using tags with same font-size and line-height, height will be 21px</span>
</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
CSS
body
{
line-height: 20px;
font-size: 14px;
}
.smaller
{
font-size: 12px;/*I prefer to use px over em, same as 0.9em*/
vertical-align: middle;
line-height: 12px;/*use any smaller line height compared to siblings*/
}
.abcd span{
text-decoration: underline;
}
OR Please follow this link https://jsfiddle.net/osha90/meeLL0u9/4/
line-height: 1em;
将此样式添加到.smaller
,bullet将垂直对齐到中心。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.