行高和行距
line-height
是用于定于行高的css属性。什么是行高?
从上图可以清楚看到,一行文本对应会有四条线,由上而下分别是 顶线(top line),中线(middle line),基线(baseline),底线(bottom line)。根据这些线,可以清晰地认知:
- 行高:相邻两行基线(baseline)间的垂直距离
- 行距:上一行的底线(bottom line)和下一行的顶线(top line)的垂直距离
line-height 的取值
line-height: normal | <number> | <length> | <percentage> ;
初始值 : normal
继承 : 是
适用元素:几乎全部,包括伪元素::first-letter和::first-line
-
line-height
初始值为normal
,这个值大概等于数值上的1-1.2
,因元素的font-family
不同而不同。 - 取值
<number>
时,应为纯数字,不带单位,最终line-height
的值等于元素的字体大小值乘以该数值,即font-size * number
。 - 取值
length
时,应该是一个带单位的长度值,比如说em
,px
,rem
等等。 - 取值
<percentage>
时,是一个百分比数值,最终line-height
的值等于元素的字体大小值乘以该数值,即font-size * number
。
要注意<number>
和<percentage>
之间的区别,它们两个计算自身的line-height
方式和结果都是完全一样的,但区别就在于继承方式上,对子元素影响方式不一样。
- 使用
<percentage>
元素得出的line-height
值会转换成length
形式的px
值,然后再把这个值继承给它的子元素。
举例说,父元素设置了font-size: 20px; line-height: 150%;
,父元素自身的行高就是20px * 150%
,即30px
。那么子元素得到的line-height
属性的继承值就是30px
,而非150%
。(有点em
的意思) - 使用
<number>
元素会先把<number>
继承给它的子元素,再由子元素自己去计算line-height
值。
举例说,父元素设置了font-size: 20px; line-height: 150%;
,那么子元素line-height
属性的继承值就是1.5
,子元素的行高由子元素本身的font-size * 1.5
得出。
因此,在实际场景中使用line-height
属性使用<number>
类型的值是较好的做法,因为你不知道<percentage>
的继承方式会不会导致一些不可预料的错误,譬如
子元素字体比父元素更大时,使用<percentage>
继承得到的行高就显得有些不够用了,相对而言<number>
实用性更强!
line-height 的实际应用和效果
首先,要认识inline content
(行内内容)、inline box
(行内框)和line box
(行内框),这三个概念和line-height
紧密关闭!(第一个概念是我自己编的)
由上图可见:
- 蓝色框是指
div
的高度,也是inline box
(行内框)和line box
(行内框),由于inline box
和line box
是不可见的,所以描述对应的图不太准确,自己领会吧! - 灰色底的区域就是
inline content
(行内内容)
那么inline box
(行内框)和line box
(行内框)有什么不一样呢?可以说,line box
(行内框)是由一个或多个inline box
(行内框)形成的,line box
(行内框)的高度由其中高度最大的inline box
(行内框)决定。继续上个例子,对a
标签设置line-height: 100px;
,可以得到:
(行内元素之间还是对齐的,因为
vertical-align
的关系,迟点再学习它)
下面说说line-height
和height
之间的关系。
平时我们输入一对空内容的<div></div>
标签时,浏览器渲染出来div
的高度为0
,那么当我们输入文字的时候,div
就有了高度,这个高度是因为文字大小撑起来的吗?答案:不是,是由line box
撑起来的。看下面个例子:
<style>
</style>
<div>
我是div里的内容
</div>
<style>
div{ line-hright: 1px; }
</style>
<div>
我是div里的内容
</div>
可以看到,高度确实是由line box
撑起来的。那么,既然line-height
和height
之前的关系如此暧昧,我们是不是可以利用起来?
是的,比如说:多行文本在容器内的垂直居中。
<style>
div{ width: 100px; border: 1px solid #ccc; text-align: center; line-height: 100px;}
span{ line-height: 16px; display: inline-block; vertical-align: middle; }
</style>
这里有要注意的一点,就是当span
的display: inline-block;
去掉后,居中效果就没有了,为啥呢?答案就在于line box
的数量,毕竟一行一个line box
嘛,领会!
上面这个技巧,可以用于图片在容器内的垂直居中吗?答案是,NO!
开头在介绍使用元素的时候,写了“几乎全部”,那么就有一些元素对line-height
是不感冒的!在这里列出来规则:
- 对于块级元素,CSS属性line-height指定了元素内部
inline box
的最小高度 - 对于非替代行内元素,line-height用于计算自身包含的匿名
inline box
的高度。 - 对于替代行内元素,如
img
或其他object
元素,line-height
没有作用。
什么是替代元素和非替代元素?
- 非替代元素即内容即显示的元素,如
div
、p
等等大部分元素,里面的内容会立即显示。 - 替代元素会根据元素标签,属性等决定显示内容,如
img
,你得有src
属性,下载图片才能显示出来。
规则是在 MDN - line-height 上摘过来的,但是经过实验发现,不是所有的替代行内元素都对
line-height
不感冒。
要注意的是,上面 MDN 的规则中关于替代元素的描述仍然是正确的!(也许你看完后面的应该再回过头来想想)
首先说说input
。input
的替代性在于它的type
标签,type
不一样,效果和功能就完全不一样,下面是所有的input type
:
input type : text | button | submit | radio | checkbox | file | hidden | image | password | reset ;
列举其中2个试验场景:
试验1:
<style>
*{margin: 0; padding: 0;}
body{ line-height: 50px; }
input{ line-height: 30px; }
</style>
<input type="text" value="i am input">
试验2:
<style>
*{margin: 0; padding: 0;}
body{ line-height: 50px; }
input{ line-height: 30px; }
</style>
<input type="text" value="i am input">
明显可以看到,input
除了hidden
类型外,其他都属于inline-block
,也就是行内元素,对块级元素body
设置行高,作为子元素的input
会有一个相对的最小line box
高度(其实是继承)。但是,对行内元素input
设置行高就不一定有效了,关键在于是否拥有(匿名)行内子元素
。input:text
和input:password
(其实file
也有,不过很奇葩)都能输入文本,里面的文本内容可以看做是input
的匿名行内子元素,它也可以撑开一个inline box
。同理,textarea
也一样,只不过textarea
可换行,拥有多个inline boxes
。
总而言之,就是要看容器内有没有匿名行内元素啦!