[csswg-drafts] [css-fonts] Reconsider the definition of "first available font" (#4796)

jfkthame has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-fonts] Reconsider the definition of "first available font" ==
The spec currently [says](https://drafts.csswg.org/css-fonts/#first-available-font):

> 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](https://github.com/adobe-fonts/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](https://drafts.csswg.org/css2/visudet.html#leading), or to resolve a [font-relative unit](https://drafts.csswg.org/css-values-4/#font-relative-lengths) 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.

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/4796 using your GitHub account

Received on Thursday, 20 February 2020 16:40:24 UTC