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

匿名 (未验证) 提交于 2019-12-03 01:47:02

问题:

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; }
containing div has height of 21px, not 20px
containing div has height of 61 px, not 60px 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 multiline

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.

回答1:

§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:

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; }
normal
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 multiline multiline multiline multiline multiline multiline


回答2:

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; } 

Demo at http://jsfiddle.net/gaby/b5zgpktj/1/



回答3:

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;  }
containing div has height of 21px, not 20px
containing div has height of 61 px, not 60px 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 multiline

Reference:



回答4:

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 i.e. 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

    
containing div has height of 21px, not 20px
The same problem can be replicated while using tags with same font-size and line-height, height will be 21px
containing div has height of 61 px, not 60px 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 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/



回答5:

line-height: 1em; 

add this style to .smaller and bullet will get vertically aligned to center.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!