第二天,谈谈【line-height】
先来看MDN上的总结:
- On block level elements, the line-height CSS property specifies the minimal height of line boxes within the element.
- On non-replaced inline elements, line-height specifies the height that is used in the calculation of the line box height.
- On replaced inline elements, like buttons or other input element, line-height has no effect.[1]
也就是说:
- 在*block level elements*(块元素)上使用
line-height
,也就指定了块元素内部*line boxes*的最小高度 - 在*non-replaced inline elements*上使用
line-height
,line-height
会被用来计算*line boxes*的高度。 - 在*replaced inline elements*上使用
line-height
没有效果。例如:button
或者其它input
标签。[1]
第3条规则看起来最容易理解,我们先拿它来实验下,看测试用例一:
.button-1{
line-height: 20px;
}
.button-2{
line-height: 30px;
}
.input-1{
line-height: 20px;
}
.input-2{
line-height: 30px;
}
效果如下:
出人意料的是在*replaced inline elements*上使用line-height
居然有效果,与第3条规则不符。注意到第3条规则是有注解的。还好,注解里给出了原因:
[1] Neither engine implements the correct behavior with replaced inline elements like buttons. In some cases line-height is allowed to have an effect on them. This is incorrect behavior relative to the specification.
也就是说浏览器都没有正确的实现这一效果。按照CSS规范来看,浏览器在这一效果上都错了。
接着来看第2条规则:
- 在*non-replaced inline elements*上使用
line-height
,line-height
会被用来计算*line boxes*的高度。
至于到底如何计算,它并没有说明。在介绍计算规则之前,需要先明确几个概念。用代码说话:
<p>
The <em>emphasis</em> element is defined as "inline".
</p>
显示效果如下:
上面的代码涉及到了四种盒子:
1 . *block-level boxes*(块级盒),由代码中的<p>
标签产生,它可以包含其它的*box*。
2 . *inline-level boxes*(行级盒),在<p>
标签中有一系列的*inline-level boxes*,如下:
上面的*inline-level boxes*可以分为两类,一类是由内联元素产生的,例如<em>
而余下的两个没有被标签包裹的*inline-level boxes*就被称为*anonymous inline-level boxes*(匿名行级盒),如下:
3 . *line box*,由*inline-level boxes*连接而成,每一行称为一个line box
4 . *content area*,它是围绕着文字的并且看不见的一种*box*,它的高度取决于font-size
。如下:
概念介绍完了,回到我们的问题上:
*non-replaced inline elements*如何根据line-height
来计算*line boxes*的高度
上面我们说过*line box*是由*inline-level boxes*连接而成,所以我们将问题拆成两步:
- 先探究
line-height
与*inline-level boxes*高度的关系 - 再看*inline-level boxes*的高度与*line box*高度的关系
先来看看line-height
与*inline-level boxes*高度的关系,测试用例二:
再结合下面这张图
你应该就能看明白了。
我们把line-height: 30px
与font-size: 20px
的差值10px
称为行间距(英文是*leading*)。那么半行间距(英文是*half-leading*)就是10px / 2 = 5px
。半行间距作用在*content area*的顶部和底部。
很简单,对不对?
但是别忽略了,上面计算的前提是line-height
大于font-size
,那如果line-height
小于font-size
会怎么样呢?来看测试用例三:
我们看到当line-height
小于font-size
时,*inline-level boxes*会使用line-height
作为自己的高度,此时 content area 会溢出 inline-level boxes ,如下图所示:
那么如果将line-height
设置为0
会出现啥效果呢?我们以后再探究。
至此,我们说完了line-height
与*inline-level boxes*高度的关系,接下来该看*inline-level boxes*的高度与*line box*高度的关系了。记住下面这条规则:
line box 的高度由它内部 最高的 inline-level boxes 或 replaced element 来决定。
来看测试用例四:
至此,我们终于清楚了line-height
与*line boxes*高度的关系,也就清楚了
MDN上第2条规则的含义:
- 在*non-replaced inline elements*上使用
line-height
,line-height
会被用来计算*line boxes*的高度。
需要补充的一点是:line boxes 在它的容器里是紧挨着彼此堆叠到一起的,看下图会更好理解一些:
最后,我们来看第1条规则:
- 在*block level elements*(块元素)上使用
line-height
,也就指定了块元素内部*line
boxes*的最小高度
理解这一条需要一点想象力,看着下图,开动你的想象力:
想象在每一个*line box*的起始位置都有一个宽度为零的 inline-level boxes ,我们把这个想象出来的盒子叫做*strut*(这个名字来源于TeX)。*strut*会根据继承来的font-size
和 line-height
计算本身所占高度。这个高度也就是所在*line boxes*的最小高度。
参考文献:
- http://www.w3.org/TR/2011/REC-CSS2-20110607/visudet.html#line-height
- http://www.w3.org/TR/css3-box/
- CSS布局
- 一个关于line-height非常好的PPT,本文部分图片来自这个PPT,需翻墙
说了这么多有关line-height
的问题,其实还有好多知识点没有涉及到,比如line-height
的继承问题以及0
行高问题等等。我们后面会一一探讨。