Adamwu1992 / adamwu1992.github.io

My Blog
2 stars 0 forks source link

行高的计算 #16

Open Adamwu1992 opened 5 years ago

Adamwu1992 commented 5 years ago

正如在内联格式化上下文中所言,用户代理将内联盒排列到一系列堆叠的行盒里。行盒的高度取决以下因素:

替代元素(placed elements)指的是,最终的呈现超出了CSS的定义范围的外部对象。典型的替代元素包括:

  • <iframe>
  • <video>
  • <img>
  • <embed> 在某些特定场景下一下元素也会被认为是替代元素:
  • <options>
  • <audio>
  • <canvas>
  • <object>
  • <applet> 通过CSS的content属性插入的元素,是匿名替代元素,因为它们并不存在于HTML中。

空的内联元素会产生一个空的内联盒,但是它仍然有自己的外边距,内边距、边框和行高,它对于计算的影响和有内容的元素是一样的。

Leading and half-leading

CSS假设每个字体规范都定义了一个字符处于baseline以上的高度和处于baseline一下的深度。我们用A指代高度,用D指代深度(对于给定的字体和给定的字体尺寸),并且定义从顶部到底部的距离就是A+D,这里的定义是把字体中的字符作为一个整体看待,不必纠结单个字符的上升或者下沉。

用户代理必须在非替代的内联盒中用字符的基线来对齐它们,然后再去确定每个字符的A和D,注意在一个元素中的字符可能用不同的字体和尺寸,所以它们的A和D可能不相同。如果一个内联盒不包含任何字符,它将被视作包含了一个strut(一个看不见的没有宽度的字符),A和D的计算就基于这个内联盒第一个可获取的字体。

然后我们确定每个字符的leading=line-height - AD,用L指代leading(L有可能是负数)。其中一半的L被添加到A中,另一半L被添加到D中,对于这个字符来说,高于baseline的部分A' = A + L/2,低于baseline的部分D' = D + L/2。

内联盒包含所有的字体和他们两边的half-leading的高度就等于line-height。盒子的子元素不会影响这个高度。

尽管非替换元素的外边距、边框和内边距不会被纳入到行盒的计算中,但是他们仍然会被渲染在内联盒周围。意味着如果line-height指定的高度小于内联盒内容的高度,边框这些东西会渗透进相邻的行盒中。用户代理按照文档的顺序绘制元素,这将导致后一行的边框在前一行的边框和文本上绘制。

line-height

line-height的值可以是以下任何一个:

normal取决于不同用户代理的实现,规范要求用户代理针对这个关键词设置合理的行高,不同的字体对应的这个‘合理值’都可能不同。如果一个元素中包含不同字体的字符,‘合理值’将会根据最后一个字体来计算。

如果值是一个长度,这个长度将被用来计算行盒的高度,负数非法。

如果是一个数字,相当于把字体的尺寸诚意这个数组作为line-height的值,结果会是一个长度。

如果是一个百分比,也是和字体大小计算最终值,和数字类似。

vertical-align

这个属性决定着行盒中那些内联元素生成的盒子的垂直定位。(在表格中vertical-align属性有着不同的含义)

vertical-align的值可以是以下任何一个(下面的定义中,对于非替代内联元素,用于对齐的盒子是指高度为行高的盒子,对于其他元素,对齐的盒子指的是margin box):

x-height指的是在给定的上下文中字母x的高度。

下面的值是相对于行盒的。

inline-table元素的baseline是表格第一行的baseline

inline-block元素的baseline是这个元素的常规流中最后一个行盒的baseline。例外的情况就是:

这种情况下的baseline是外边框的底部。

参考

W3C: 行高计算 x-height