对line-height和vertical-align的一些理解

Clloz · · 362次浏览 ·

最近遇到了很多关于line-height和vertical-align等行盒模型相关问题,决定单独写一篇彻底搞清楚原理。
行内元素的排列是一个很特殊的东西,不同的浏览器的表现很可能不一样。

深入理解line-height

line-height翻译成行高,指的是一行的基线到下一行基线的距离,具体的细节如图行高细节
任何一个行内框中的结构都如图所示,顶线和底线之间显示文字,他们的距离就等于font-size,中线的位置是基线向上1/2个x的高度,我们可以近似的看做x的那个交叉点。

line-height不允许负值,为font的上下间距normal的情况为默认值,浏览器会计算出“合适”的行高,多数浏览器(Georgia字体下)取值为1.14,即为font-size的1.14倍,如果未设定font-size,那既是基准值16px的1.14倍,normal和具体的数值相比,会因为字体的不同而不同。

解释一下关于上图的几个概念,

  1. content area:就是顶线和底线之间包裹的区域,高度只和font有关,宽度就和字数有关,就理解为包裹文字的一个区域。

The height of the content area should be based on the font, but this specification does not specify how.

  1. 行高、行距:行高就是相邻的文本行之间的基线的距离,这个高度包括了content area和行距。 行距就是行高减去content area的高度。

  2. inline box(行内框):所有的行内元素都会生成看不见的行内框,就是标准中的inline box,我们无法看到他,它是在浏览器渲染中使用的,在不设置其他样式的情况下,inline box的高度和content area高度是一样的。我们理解inline box的时候,其实可以不必太刻意,他也有高度。为了排版行内元素,inline box和line box都是css来规定的,inline box水平方向排列在line box里。inline box的高度并不会受内部元素的影响,我们只要设置了line-height,那么这个行内框的高度就已经确定了,就像div一样,我们只要设置了一个div的高度,不管里面的内容多长,div的高度也不会产生变化,内容超出了那就溢出了,line box也是一样,当line-height小于内部的文字的高度,内部的文字就会溢出了,见例5,我们可以看到红色背景的span超出了父元素的范围,这里的红色背景其实是content area的,不是inline box的,父元素的高度为span的line-height。这里要注意的是,父元素要设置font-size为0,因为浏览器默认字体为16px,如果不设置font-size为0的话,父元素的高度就会为16+2(border)px,还有就是要设置span的vertical-align为top,不然也会引起高度变化,原因下面讲。

  3. line box刚刚在inline box哪里我们就提到了行框line box的概念,css规定了,所有的inline box排列在line box中,这个line box的高度就是非常关键的跟我们的vertical-align还有line-height相关的,line box的高度怎么计算呢?网上大多的说法是line box中高度最高的那个inline box 决定了line box的高度,我一直觉得这种说法不严谨,应该是以inline box最高的上边界线和最低的下边界构成line box的边界,不过我没有找到例子来证明这一点,css的渲染是以line box的高度尽量小为目的,所以我想最高的inline box来决定高度也是有道理的,如果下次找到反例我会来补充。line-height决定了inline box的高度,而vertical-align则决定了inline box在line box中的位置。line box的高度由行内最高的inline box决定,但同时也可以直接用line-height来决定,给父元素设置line-height就可以给line box设定高度,而我们知道浏览器有默认字体大小,也就有默认的line-height,所以行内元素一旦确定了高度和vertical-align我们就能确定它在行内的位置。

line box的高度和inline box的vertical-align是互相依赖的,他们两者的确定都要知道对方的值。

  字母x在line-height中有很重要的作用,这里单独说一说,首先基线是以字母x的下边界为基准的,在css中有一个x-height的概念,就是用来形容x的高度,我们在css中描述大小可以用px,em,百分比,还可以用ex,这个ex就是x的高度,不过很多浏览器用0.5em,也就是字体大小的一半来渲染。

x-height示意图
1. ascender height: 上下线高度
2. cap height: 大写字母高度
3. median: 中线
4. descender height: 下行线高度

比如例子中的第三块的代码,图片高度是200px;父元素的line-height:240px,在给图片设置vertical-align的情况下,在chrome下,父元素的高度为312px,这个312px是怎么来的呢,我们给父元素里面添加一些文字,他们会生成匿名inline box,line-height为240px,图片的默认对齐方式为baseline,也就是基线和父元素基线对齐,图片没有基线,就按照bottom margin来计算。也就是我们图片的下边缘要和文字中的x的下边缘对齐,图片的下面的空间的是由基线到底线的距离加上1/2行距构成的,行距很好计算,line-height减去字体大小就得到行距,不过这个基线到底线的距离是不好计算的,目前还不知道方法。这个例子中,1/2行距为(240 – 20)/2 = 110px;图片下面的高度应该为110+x(x为基线到底线的距离),父元素的高度为200+110+x,在chrome中为312px, firefox中为312.5px,而且在我们微调字体的时候,有时候发现div的高度不会发生变化,比如设置字体为21,22等,我认为是这样的,字体增大或减小的时候,x也会随之增大和减小,字体越大,行距越小,x越大,行距和x的变化是相反的,在一定程度内,会抵消,所以微调字体的时候,不会发生变化。当我们将字体设置为0的时候,各个浏览器的表现基本一致,高度都是320。
注:以上高度均没有就算border。

Align the baseline of the box with the baseline of the parent box. If the box does not have a baseline, align the bottom margin edge with the parent’s baseline.

查看文中实例


Clloz

人生をやり直す

发表评论

电子邮件地址不会被公开。 必填项已用*标注

我不是机器人*

EA PLAYER &

历史记录 [ 注意:部分数据仅限于当前浏览器 ]清空

      00:00/00:00