font-size 真正对应的是什么?

What does font-size really correspond to?

我正在尝试查找 font-size CSS 属性 中设置的值对应的内容。

为了给出上下文,我想在 CSS 中获取我从 OS/2 指标。 em 单位与给定的 font-size 相关,OS/2 指标与 em-square 相关。

我期待的

我的期望基于以下参考资料。我没有发现更清楚或更精确的东西。

  1. 根据W3C reference for font-size in CSS2.1, and as quoted in all the Stack Overflow questions I found on the topic (here, here and here):

    The font size corresponds to the em square, a concept used in typography. Note that certain glyphs may bleed outside their em squares.

  2. 根据我在排版方面的一些知识,em square 是字体度量的整个正方形,其中定义了上升、下降、间隙、(等...)线。在 OS/2 指标中,em square 是字体本身的大小(通常为 1000 或 2048 UPM)。


    (来源:microsoft.com

    我从 W3C 找到的唯一解释是 old reference from 1997 for CSS1,它与我使用的 em square 的现代数字定义一致:

    Certain values, such as width metrics, are expressed in units that are relative to an abstract square whose height is the intended distance between lines of type in the same type size. This square is called the EM square. (...) Common values are 250 (Intellifont), 1000 (Type 1) and 2048 (TrueType).

因此,如果我正确理解这些引用,font-size 中指定的 值应该用于生成 整个 em square的字体,我们应该可以根据字体的大小和规格计算出一部分字体的大小。

例如,与...

.my-letter {
    font-family: 'Helvetica Neue';
    font-size: 100px;
    text-transform: uppercase;
}

...我们应该有 100pxem square,因为 Helvetica Neue 的大写高度为 714 / 1000sCapHeight 在 OS/2 table), 大写高度 71.4px.

实际发生了什么。

生成的em squarefont-size(在最新版本的Chrome、Firefox和Safari上测试Mac).起初,我以为浏览器对 em square 有其他定义,并且正在使字母的 部分 等于 font-size,但我没有找到任何OS/2 个与之匹配的指标(有或没有上升、下降、间隙...)。

您还可以看到this CodePen。请注意,我使用 line-height: 1; 来突出显示预期大小,但我的问题是 font-size("rendered ink")而不是 line-height("collision box")。这是我必须明确的事情,因为我已经被误解了好几次。 line-height不是问题.


所以我有三个问题:

  • 我是否正确理解了 W3C 参考资料,或者我在假设这些参考资料没有说明的事情?
  • 如果不是,为什么生成的字体的 em 方块大于 font-size
  • 最重要的:我怎么知道渲染的em-square(相对于font-size)的大小?

感谢您的帮助。

您对 W3C 参考文献的理解是正确的,但您对红框的理解是错误的。

红框未描绘em-square。它的高度是指标上升和下降的总和。

article(已在现已删除的答案中共享)解释得很好。这是我试图把它变成一个独立的答案。

假设我们有一个带有 font-family: Robotofont-size: 48px 样式的 <span>,我们想回答这个看似简单的问题:跨度的有效高度是多少?剧透:它是 65px。您可以这样推导出它:

首先,您需要了解有关字体的一些指标。如果你在 Linux 上,你可以用 FontForge 检查字体,如下所示:

$ fc-list | grep Roboto
$ fontforge /usr/share/fonts/truetype/roboto/hinted/Roboto-Regular.ttf

Element => Font Info... => General下你可以得到Em Size,它有点像字体的无单位基本单位:

Element => Font Info... => OS/2 => Metrics下可以找到ascent/descent,这是最大的字体扩展名:

浏览器所做的是将 em 大小 (2048) 与指定的字体大小 (48px) 相匹配。在此基础上,它计算 ascent/descent (2146, -555) 覆盖的区域与 em 大小的关系。所以公式大致是:

result_size = (ascent + |descent|) / em_size * font_size

在这个例子中:

(2146 + 555) / 2048 * 48px = 63.375px

剩下的问题是为什么浏览器实际上到达 65px 而不是。我的假设是上升和下降是单独汇总的。单独应用公式给出 50.30px => 51px 的上升和 13.01px => 14px 的下降,结果正好是 65px.