#666: Review Request: CSS Fonts src: descriptor syntax for client side font selection

Visit on Github.

Opened Aug 9, 2021

I'm requesting a TAG review of the extended format() and supports(<technology>) syntax of the src: descriptor of @font-face, see 4.3.1. Parsing the src descriptor of the CSS Fonts spec.

src: ... [ format(<font-format> [supports <font-technology>#]?)]?

The extended syntax serves as a means for the UA to select the most advanced font technology from a list of stated font sources, by traversing the list and selecting the first for which the UA provides support.

As Chrome would be the first browser to ship support for the supports(<font-technology>) I am requesting TAG review.

Because the specification also mandates the UA to drop unsupported entries from the list of sources specified in the @font-face src: line, this syntax can be used together with JavaScript accessing the CSSOM in order to detect which features are supported. This provides desired feature detection capabilities before the introduction of the COLRv1 font format.

Feature detection of font formats is already possible through canvas based methods, see more details in the additional security and privacy considerations below.

Further details:

  • I have reviewed the TAG's Web Platform Design Principles
  • Relevant time constraints or deadlines: ideally as soon as possible, as we'd like to have a way of COLRv1 font format feature detection available before shipping COLRv1
  • The group where the work on this specification is currently being done: CSS WG
  • Major unresolved issues with or opposition to this specification:
    • No major unresolved issues, TAG review requested mainly as we would be the first to ship in Chrome and considerations listed below.
  • This work is being funded by: Google

Additional considerations

Additional privacy considerations

In addition to the security and privacy self-questionnaire of the CSS fonts spec:

What information might this feature expose to Web sites or other parties, and for what purposes is that exposure necessary? Do features in your specification expose the minimum amount of information necessary to enable their intended uses?

Font technology support can generally be detected using Canvas methods, compare https://pixelambacht.nl/chromacheck/ made by @RoelN. Exposing font technology support in this syntax would thus not expose fundamentally new information.

In the Blink-dev intent-to-ship @krgovind also asked, "...whether this mechanism could reveal anything more granular than the major version of the user agent. Is it possible for font technology support to evolve faster than major UA versions (e.g. via OS stack updates, or in minor UA versions)?"

I responded, that it depends on whether we look at a particular implementation or look at the spec conceptually:

Speaking for Chrome, changes in which font technologies are supported would usually coincide with a major version of the user agent, indeed, or switching a flag on when using a rollout via Chrome variations/flags. In Blink, we use a hybrid font stack that is composed of the system font stack's rasterising capabilities (DirectWrite, CoreText) combined with Skia +FreeType's rasterisation capabilities to fill in gaps in the system rasteriser. Using this stack, we can provide support for all the font formats we support (OpenType variations, color font formats: COLRv0, SBIX, CBDT) on all OSes where we have our own engine (iOS excluded). This means we would not reveal any font technology support differences using this feature as we can cover the gaps with the Skia+FreeType backend.

However, at the specification level, conceptually, this feature can reveal more than the user agent major version if in non-Chrome implementation platform font support differs and a UA provides different support on different platforms. Firefox, as an example, does not have a hybrid font stack capability so their font technology support differs on different platforms. So a correct implementation of this feature in a UA that supports some font technologies only on some platforms would reveal information about the underlying OS/platform as well - so the granularity is similar to UA major version + platform (Win, Mac, Linux, etc.).

Relationship to server side negotiation

During the discussion on blink-dev the question was brought up by @yoavweiss in how this feature compares or relates to

  • server-side content negotation techniques such as the Accept: header or client hints
  • preload optimizations with their type attribute for pre-requesting resources.

Server-side content negotiation at the time of requests to font blobs or CSS stylesheets are additional tools for selecting the right font content. Preload optimisations as well.

We concluded that there is room for improvement for server side negotiation when requesting font resources. Currently, third-party font providers such as Google Fonts make use of user agent information to decide what CSS to ship. Additional discussions showed that improving this server-side content-negotiation should likely be done through extending UA client hints to give indication about supported font technologies. We concluded that mapping a set of font-technologies supported by the UA to a set of mime-types is likely not a good approach.

In any event, both (server-side content negotiation, preload optimizations) and client side content selection of font resources through the advanced @font-face src: ..supports(<font-technology>) syntax provide useful tools at different stages of fetching and rendering content, which both serve different needs.

Quote from @yoavweiss on blink-dev:

I was initially concerned by the fact that these technologies are not well represented in the relevant mime type that can then be used for selection in preload and as part of the Accept header. But given the fact that preload's type based selection is breaking at the seams when it comes to image types as well as in the face of many different font features, with different levels of support across browsers, it seems like it may be time to design a separate selection mechanism there that wouldn't rely so heavily on mime types. Regarding Accept, after further thinking, I was not excited about adding the font capabilities to that header because: a) it may expose more passive entropy b) the content-negotiation for fonts is often needed when serving the stylesheet, and sending Accept values for fonts as part of the stylesheet request felt weird. Talking to the Privacy Sandbox folks, they seem to generally agree with (a) and that we may need an alternative mechanism to enable font capabilities based content negotiation.

As such, I think it's fine that this feature is considering the various font capabilities as an orthogonal dimension to font formats and enabling client-side content-negotiation based on that. That seems like an important use case.

We'd prefer the TAG provide feedback as:

💬 leave review feedback as a comment in this issue and @-notify @yoavweiss @svgeesus @jfkthame

Discussions

2021-08-16

Minutes

Rossen: Adding comments and closed.

2021-08-16

Minutes

Lea: Chrome is interested in pushing this forward fast

Rossen: I'm very aware of the origin of this work, but not familiar with the current exposure through CSS. The color v1 format stuff and some of the addtiions that they were intending to add for colour fonts and added gradient support which is going to bring that work close to the capabilities of things like svg fonts on the lower font capability level. Sounds like they want to expose this through CSS afterwards. Sounds pretty good to me.

Lea: I was not involved in the CSS WG discussions. I just caught up today. This is not about adding specifically capabilities, this is about adding feature detection for these capabilities so that authors can load different font files depending on what the browser supports. Right now even though these technologies are designed to be forwards compatible and you can load a colour font in browsers that don't support it you probably don't want to load huge files in browsers that can't take advantage of them. There is no explainer.. I needed to do some hunting down to figure out examples of usage and user needs.. After this digging, I do now think there is a strong need for this. A bit skeptical about the syntax, though CSS WG specs are often well thought out so maybe I'm missing something. Currently CSS has an existing feature detection mechanism (@supports) and this is adding an entirely separate microsyntax. I personally find it hard to read. First, it is just a list of keywords with no hierarchy: format specifier, supports keywords, and feature detected features all look the same. But primarily, it's unclear whether this is a feature detection for the browser or telling the browser what the font can do. I know which one it is after reading, but just looking at the syntax, I wouldn't know what it does. My bottom line is the functionality is needed, not sure about if this is the best way to expose it.

Rossen: I'm going to ask for an explainer.

Lea: the spec itself only has one example.. revisit in plenary to see if they provided explainer?

Rossen: if this is time sensitive hopefully they will get back to us

Peter: about the supports mechanism.. if you don't have the microsyntax in the source description, how would you do it? Wrap font face in an @support rule?

Lea: we resolved to be able to nest @supports rules inside regular rules, so we could also allow them inside @font-face. I posted a proposal about this to the CSS WG repo after looking at this, with my CSS WG hat on

Peter: putting @supports around the individual descriptor?

Lea: yep, and current browsers only get rid of the @supports rule, not the entire @font-face rule, so it is backwards compatible. I must be missing something.. we'll see.

Peter: normally @supports doesn't dig into these microfeatures

Lea: See, it was originally designed for property value pairs but it does have a selector() function.. so it does allow for testing specific capabilities.. you could conveive a font-technology() function or something like that.

Peter: my extremely weak argument would be you can make the same argument for the format of the descriptor, that it should be in a supports rule around it

Lea: the format predates @supports by many years

Peter: I'm sure it does.. but as far as the mechanism goes, it's six of one and half a dozen of the other.. not disagreeing.. just looking from all angles. I think I tend to agree we should keep supports like things in @supports

Lea: if we only have one feature querying mechanism in CSS that would be a good thing

Rossen: we definitely need to exhaust the possibilities of @supports before we consider anything else

Lea: looking at discussions, I didn't see one about using @supports. All about do we use the format function or a separate supports function inthe src descriptor... am I missing something obvious? to nest conditional rules inside other rules is fairly recent

Rossen: a couple of conversations here.. one around whether or not this capability makes sense and the approach for this feature is a good addition to the overall platform. That's us saying yes or no.. the other discussion is all of the details and how we're going to spec this out in CSS WG. We will go and do that in CSS WG, we'll make sure that @supports is the way to go and why is this not considered. I don't want us to come too heavy handed from the CSS pov in terms of feedback here

Lea: we don't want to design the feature

Rossen: right..

Peter: there were some resolutions in CSS WG about adding this.

Lea: it is part of the fonts 4 spec, no implementations yet. Definitely part of the draft. Since there's no explainer we can wait until plenary.

Rossen: knowing how much push they have on the lower font capabilities this is the icing on the cake. They are at the final stretch with all of that work. It's good to see that come together.

Lea: this functionality is really needed