Skip to content

规范之路-line-height的工作原理

Posted on:2014-11-20 11:45

有人问我,“line-height到底是怎么一回事?”,“元素高度到底是怎么计算出来的?”。我说不出个所以然……

故有此文

首先有一点我们需要明白的是:在标准的盒模型中,height属性定义的是盒子中内容的高度。而line-height属性只能作用在行级的非替换元素上(什么是非替换元素),指定了元素形成的line box的最小高度。

常见的例子就是大段的文本了,当你对一个段落设置了固定的高度时,要么内容不多底部出现了空白,要么内容太多溢出了容器,这也是显而易见的。但是在这种情况下,是无法直接影响到文本的排版。

一个没有设置高度的段落,当包含文字的时候,它会自动获得一个恰好可以包裹着文本内容的高度。其本质是文本形成的line box具有高度而将段落撑开。此时,line box的潜在的高度的决定因素就是line-height

那么到底line-height是如何工作的呢?

先来看看W3C官方给出的解释:

The height of a line box is determined as follows:

大致的意思是,一个line box的高度有下面列举的情况来决定:

CSS假定每一种字体的字体规格,指定了一个在基线上方的高度和基线下方的depth(也就是两个值)。通俗的来说,就是字体占据高度,基线从所占据的高度穿过。假设用A代表基线上方的高度(指定大小的具体字体),D代表基线下方的depth,同时AD = A + D代表从上到下的距离。

在非替代元素中,用户代理一定会将所有的图像字符基于他们的基线对齐。对于每一个文字形成的字符图形来说,决定了A和D。这里所说的字符图形(glyph)是一个单独的元素可能由不同的字体组成,他们的A和D不一定相同。如果一个行级盒子没有任何的字符图形(glyph),我们认为它将包含一个strut(一个宽度为零,高度为AD的不可见的glyph)。

每一个字符图形都定义了一个leading L,其中 L = 'line-height' - AD。leading的一半添加到A的上面,另一半添加到D的下面。所以最终呢,在基线之上A' = A + L/2,在基线之下D' = D + L/2。说的直白一点,就是字体本身占据高地,当添加了line-height属性之后,L不能为负数。

inline 盒子的高度将所有的字符图形和它们上下的 hadf-leading 包裹在一起,这个高度就是我们说的“行高”(这一行的高度,不等同于line-height的值)。盒子的子元素不受这个高度的影响,

尽管margin,padding和border不会纳入inline box的高度的计算中,但是它们依旧会在盒子周围渲染。这意味这,如果指点高度的line-height的值比盒子的内容的高度小,那么padding和border的背景和颜色会流入到邻接的line box中。因为渲染顺序的关系,导致后面的line box 的boderh会覆盖前面line box的border和文本。

line-height的值

说了这么多,现在来看看line-height的使用

line-height呢有这么几个值

当一个元素中的文本包含不止一种字体时,用户代理可能会根据最大的字体大小来设置line-height的normal值。

Specified, computed, and actual values的简单解释

当用户代理解析一个文档,创建出一个DOM树时,针对当前的媒体设备,为每一个元素的每一个属性指定一个属性值。

元素属性最终的值取决于一个“四步计算”的结果:

  1. 浏览器对元素设置的默认样式(‘specified value’)
  2. 使用继承自祖先元素的值(‘computed value’)
  3. 如果有必要,转换成一个绝对的值(‘used value’)
  4. 最后根据当时的环境转换属性值(‘actual value’)

参考:
W3C line-height W3C Assigning property values