深入剖析 CSS:字体度量、行高和垂直对齐( 二 )


每个HTML元素实际上是一堆行框 。 如果您知道每个行框的高度 , 则知道元素的高度 。
如果我们像这样更新以前的HTML代码:
<p>Gooddesignwillbebetter.<spanclass=''a''>Ba</span><spanclass=''b''>Ba</span><spanclass=''c''>Ba</span>Wegettomakeaconsequence.</p>
它将生成3个行框:
第一个和最后一个都包含一个匿名内联元素(文本内容)
第二个包含两个匿名内联元素 , 3个<span>
深入剖析 CSS:字体度量、行高和垂直对齐
文章图片
(黑色边框)由包含内联元素(实线边框)和匿名内联元素(虚线边框)的线框(白色边框)组成<p>我们清楚地看到 , 由于第二个行框的子级计算内容区域 , 更具体地说 , 使用双体船字体的行框比其他行框高 。
行框创建中的困难之处在于 , 我们无法真正看到 , 也无法用CSS控制它 。 即使将背景应用于也不会给我们任何关于第一行框高度的视觉线索 。 ::first-line
line-height:对问题及其他
到目前为止 , 我引入了两个概念:内容区域和行框 。 如果你读得很好 , 我告诉过一个行框的高度是根据它的孩子的高度来计算的 , 我没有说它的孩子内容区域的高度 。 这会产生很大的不同 。
尽管这听起来很奇怪 , 但内联元素有两种不同的高度:内容区域高度和虚拟区域高度(我发明了术语“虚拟区域” , 因为高度对我们来说是不可见的 , 但你不会在规范中找到任何内容) 。
内容区域高度由字体指标定义(如前所述)
虚拟区域高度是行高 , 它是用于计算行框高度的高度
深入剖析 CSS:字体度量、行高和垂直对齐
文章图片
内联元素具有两种不同的高度话虽如此 , 它打破了基线之间距离的普遍看法 。 在CSS中 , 它不是line-height3.
深入剖析 CSS:字体度量、行高和垂直对齐
文章图片
在CSS中 , 行高不是基线之间的距离虚拟区域和内容区域之间计算的高度差称为前导 。 此行距的一半添加在内容区域的顶部 , 另一半添加在底部 。 因此 , 内容区域始终位于虚拟区域的中间 。
根据其计算值 , (虚拟区域)可以等于、高或小于内容区域 。 对于较小的虚拟区域 , 行距为负数 , 行框在视觉上小于其子区域 。 line-height
还有其他类型的内联元素:
替换了内联元素(、、等)<img><input><svg>
inline-block和所有元素inline-*
参与特定格式设置上下文的内联元素(例如 , 在flexbox元素中 , 所有flex项都被块化))
对于这些特定的内联元素 , 高度是根据其和属性计算的 。 如果是 , 则使用 , 并且内容区域严格等于 。 heightmarginborderheightautoline-heightline-height
深入剖析 CSS:字体度量、行高和垂直对齐
文章图片
内联替换元素、内联块/内联和块化内联元素的内容区域等于其高度或行高无论如何 , 我们仍然面临的问题是的价值是多少?至于内容区域*高度的计算 , 答案可以在字体指标中找到 。 line-heightnormal
因此 , 让我们回到FontForge 。 双体船的em-square是1000 , 但我们看到许多上升/下降值:
将军上升/下降:上升者为770 , 下降者为230 。 用于字符绘制 。 (表“OS/2”)
指标上升/下降:上升者为1100 , 下降者为540 。 用于内容区域的高度 。 (表“hhea”和表“OS/2”)
公制线距 。 用于 , 通过将此值添加到上升/下降指标 。 (表“嗯”line-height:normal)
在我们的例子中 , 双体船字体定义了一个0单位的行间距 , 所以行高:正线将等于内容区域 , 即1640个单位 , 即1.64 。