Skip to content

[css-fonts] Reconsider the definition of "first available font" #4796

@jfkthame

Description

@jfkthame

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.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions