Glyphs vs Content Area

CSS权威指南”基本视觉格式化”一章中讲到:
对于行内非替换元素或者匿名文本来说, font-size指定了它们的content area的高度, 由于inline box是由content area加上上下的half-leading构成的, 那么如果元素的leading为0, 在这种情况下, font-size指定了inline box的高度.

<div style="background-color: teal;">
<span style="font-size: 80px; line-height: 1em; background-color:grey; opacity: 0.7; padding: 0">Lorem maiores atgfyq.</span>
</div>

以上的例子, font-size和line-height都设置为80px, 按理说span的inline box就是80px.

但是从开发者工具看, 拥有绿色背景的div的高度才是80px, 不懂为什么span的高度要比80px大呢?

issue-line-height

原因书中也提到了:

Even in cases where you try to keep inline nonreplaced element backgrounds from overlapping, it can still happen, depending on which font is in use. The problem lies in the difference between a font’s em box and its character glyphs. Most fonts, as it turns out, don’t have em boxes whose heights match the character glyphs.

That may sound very abstract, but it has practical consequences. In CSS2.1, we find the following: “the height of the content area should be based on the font, but this specification does not specify how. A user agent may…use the em box or the maximum ascender and descender of the font. (The latter would ensure that glyphs with parts above or below the em box still fall within the content area, but leads to differently sized boxes for different fonts.)”

In other words, the “painting area” of an inline nonreplaced element is left to the user agent. If a user agent takes the em box to be the height of the content area, then the background of an inline nonreplaced element will be equal to the height of the em box (which is the value of font-size). If a user agent uses the maximum ascender and descender of the font, then the background may be taller or shorter than the em box. Therefore, you could give an inline nonreplaced element a line-height of 1em and still have its background overlap the content of other lines.

也就是说, 其实font-size指定的是em box的高度, 而不是内容区的高度. 浏览器可能根据字体的em box来绘制内容区, 也可能根据字体的实际字形的来绘制内容区.

如果一个字体的字形和em box高度相等, 那绘制出来的框就是font-size指定的.

如果em box和字形不等, 像截图中使用的Times字体, em box是2048, 实际字形是2355, 那么因为chrome是根据实际字形来绘制内容区的, em box被指定了80px, 那对应的实际字形就是(2355/2048)*80=92px, 和截图是吻合的.

结论如截图所言: 用CSS无法做到真正准确的格式编排.

如果想让绘制出来的字体是80px高, 可以把span改成block或inline-block, 其他不变(如果很介意字体把头脚伸出窗外, 可以用overflow截掉, 或者把字体调小一点)

line-height-issue-2

参考:

iamvdo