境界线上的馒头卡

分类:
标签:
评论:
2014年4月3日 04:31
3 Apr

line-height数值 vs 百分比

这两天在啃《CSS权威指南(第三版)》,读到line-height的部分有点迷糊,于是在网上翻了点资料,在此整理下思路。

属性

W3school上对line-height属性只有一句话的解释:

line-height 属性设置行间的距离(行高)。

看似简单明了,但其实这个属性有很多猫腻。本文先不涉及line-height的显示机理,来看看这个属性可以取什么值吧。

描述
normal 默认。设置合理的行间距。
number 设置数字,此数字会与当前的字体尺寸相乘来设置行间距。
length 设置固定的行间距。
% 基于当前字体尺寸的百分比行间距。
inherit 规定应该从父元素继承 line-height 属性的值。

一个个说过来:

  • normal:这是默认值,一般等于 1.2 (依用户代理不同可能取 1.0~1.2 ),所以实质上就是number
  • number:这个数字的意思就是倍数,如果元素的font-size16pxline-height1.5 ,那么就等于 16px X 1.5 =24px
  • lengh:直接定义一个单位数值,比如 20px2cm 。注意取 em 单位时,其实也相当于下面提到的%。
  • % 如果元素的font-size16pxline-height150% ,那么就等于 16px X 150% = 24px 。没错,看起来似乎和number没多大区别
  • inherit:直接继承父元素的line-height

于是问题的关键就出在number和百分数上了,把问题具体一点, 1.5150% 有什么区别? 这就得做测试了。(以下测试均在Safari 7.0.3上进行)

测试

先从单独的p元素开始测试(不涉及继承)。

测试一:父元素 line-height: 150% ,无子元素

<p style="font-size: 16px; line-height: 150%; background-color: gray; color: white;">
I'm so happy, that I've found you.
</p>

效果如下:

I'm so happy, that I've found you.

测试二:父元素 line-height: 1.5 ,无子元素

<p style="font-size: 16px; line-height: 1.5; background-color: gray; color: white;">
I'm so happy, that I've found you.
</p>

效果如下:

I'm so happy, that I've found you.

如预想的一样,测试一和二没有区别!p元素的行高均为 24px 。但是等等,如果我们在p中再内联一个font-size不同的span元素呢?

测试三:父元素 line-height: 150% ,子元素 line-height 继承

<p style="font-size: 16px; line-height: 150%; background-color: gray; color: white;">
I'm so <span style="font-size: 32px; color: red;">happy</span>, that I've found you.
</p>

效果如下:

I'm so happy, that I've found you.

看起来行高有点不够happy啊…… 我们用网页检查器看一下,span元素的line-height还是只有 24px 。 why? 按理说应该是 32px X 150% = 48px 啊?这中间一定有什么误会,但容我们先放一放,先来看看下一个测试。

测试四:父元素 line-height: 1.5 ,子元素 line-height 继承

<p style="font-size: 16px; line-height: 1.5; background-color: gray; color: white;">
I'm so <span style="font-size: 32px; color: red;">happy</span>, that I've found you.
</p>

效果如下:

I'm so happy, that I've found you.

hmm... 可以很明显看出p元素被span撑高了,再来看一看span的行高,这次终于是 48px 了。

测试五:父元素 line-height: 150% ,子元素 line-height 150%

<p style="font-size: 16px; line-height: 150%; background-color: gray; color: white;">
I'm so <span style="font-size: 32px; color: red; line-height: 150%;">happy</span>
, that I've found you.
</p>

效果如下:

I'm so happy , that I've found you.

哦,这次也正常了。这么说只要显式声明了line-height的值,就能得到我们想要的结果。

解决

综合上面五个测试的结果,我们很容易发现问题就出在继承上。哪里和我们预想的不一样?

对于line-height属性来说,如果使用百分数(或者em单位),子元素继承的是父元素的计算值,而非声明值!

测试三中,p元素的line-height声明值为 150% ,计算值为 16px X 150% = 24px 。接下来span元素继承了计算值 24px

而在测试四中,p元素的line-height声明值为 1.5 ,计算值为 16px X 1.5 = 24px 。但因为 1.5 并非百分数而是一个绝对值,所以span元素继承了声明值 1.5 ,并把它和本身的font-size进行计算,也就是 32px X 1.5 = 48px

这样看起来要解决这个问题的方法只有两个:

  1. 在每个子元素中显式声明line-height
  2. 在父元素中对line-height值使用绝对值

方法一实在太麻烦了,因此该选哪边一目了然。

参考:Line Height (中文版)