-
Notifications
You must be signed in to change notification settings - Fork 741
Description
The spec currently says:
The first available font, used for example in the definition of font-relative lengths such as 'ex' or in the definition of the 'line-height' property is defined to be the first available font that would match the U+0020 (space) character given font families in the 'font-family' list (or a user agent’s default font if none are available).
I recently landed a patch to make Gecko conform more closely to this behavior, but backed it out because it caused significant regressions. On looking into things, I think the behavior specified here is not in fact desirable or helpful, and should be altered.
The problem arises because of the text "that would match the U+0020 (space) character". This, by any logical reading I can think of, means that a font that does not support U+0020 is not eligible to be considered the first available font, and therefore the next in the list (or the browser's default) must be used as the basis for 'ex' or line-height computations.
This leads to poor behavior when a site does something like
.foo {
font-family: "my-icons", "Blank";
}
@font-face {
font-family: "my-icons";
src: url("my-icons.woff2") format("woff2");
}
@font-face {
font-family: "Blank";
src: url("data:font/opentype;base64,T1RUTwAKAIAAA ....");
}
(this is simplified from CSS on tumblr.com), where "my-icons" is an icon font that supports only a set of PUA codepoints; it does not have any regular ASCII characters, not even <space>
; and "Blank" is the Adobe Blank font in base64 format. It's presumably used here to avoid the PUA codepoints for the icons getting rendered as hexboxes/last-resort glyphs/tofu/whatever while waiting for the real icon font to load.
However, when the browser needs to refer to the ascent and descent of the first available font during computation of leading and half-leading, or to resolve a font-relative unit such as 'ex', it should -- if it accurately implements this part of the spec -- ignore the "my-icons" font, because that font does not "match the U+0020 (space) character", and therefore it must look at "Blank" to get the metrics to use.
This is unfortunate in this example because "Blank" has a 'cmap' table that maps all one million-plus possible Unicode codepoints to its 2K empty glyphs, and although the font data is not especially huge, it may take a long time to load this font.
It would be similarly unfortunate if the second font were a large webfont resource that would end up getting downloaded only to provide the size of the 'ex' unit (for example), or the normal line height of an empty element. But that seems to be what the spec text requires.
My testing indicates that browsers currently do use metrics from the "my-icons" font in an example like this, contrary to the spec. If the @font-face
rule is given a unicode-range
descriptor that excludes U+0020, then they do not treat it as the first available font, which corresponds with the cases discussed in #1765.
I think the problem is that in addressing the earlier issue, the spec text defining first available font was written in such a way that it appears to care about actual character support in the font, whereas what was really of interest was potential character coverage as specified by unicode-range
.
My suggestion, therefore, is to modify the definition quoted above to something like:
The first available font, used for example in the definition of font-relative lengths such as 'ex' or in the definition of the 'line-height' property is defined to be the first available font that is not excluded by a
unicode-range
descriptor from matching the U+0020 space character, given font families in the 'font-family' list (or a user agent’s default font if none are available).
A webfont without an explicit unicode-range
descriptor, or a locally-installed font used directly via font-family: <name>
, will always be eligible to be the first available font, regardless of whether it supports U+0020 or not. Only webfonts that explicitly (using unicode-range
) declare their non-support for U+0020 will be excluded.