I've been crafting a nice font-face fallback, something like this:
@font-face { font-family: fallback; src: local('Helvetica Neue'); ascent-override: 85%; descent-override: 19.5%; line-gap-override: 0%; size-adjust: 106.74%; }
It works well, however Safari doesn't yet support ascent-override
, descent-override
, nor line-gap-override
in @font-face
blocks. It does support size-adjust
though.
Since my code requires all 4, the results with size-adjust
-only look bad. Worse than no overrides. Easy-peasy I thought, I'll target Safari and not give it any of the 4.
I wanted to use @supports
in CSS to keep everything nice and compact. No JavaScript, no external CSS, all this is for a font fallback, so it should be loaded as early in the page as possible, together with the @font-face
.
Unfortunately, turns out that for example both
@supports (ascent-override: normal) {/* css here */}
and
@supports (size-adjust: 100%) {/* css here */}
end up with the "css here" not being used.
In fact even the amazing font-display: swap
is not declared as being @support
-ed.
Using the JavaScript API I get this in Chrome, Safari and Firefox:
console.log(CSS.supports('font-stretch: normal')); // true console.log(CSS.supports('font-style: normal')); // true console.log(CSS.supports('font-display: swap')); // false console.log(CSS.supports('size-adjust: 100%')); // false console.log(CSS.supports('ascent-override: normal')); // false
Huh? Am I using @supports
incorrectly? Or browsers forget to update this part of the code after adding a new feature? But what are the chances that all three make the same error?
It's not like anything in @font-face
is not declared @support
-ed, because font-style
and font-stretch
are.
Clearing out my confusion
Ryan Townsend pointed out what font-style
and font-stretch
work because they double as properties not only as font descriptors. So turns out font descriptors are not supported by @supports. Darn!
Noam Rosenthal pointed out this github issue, open in 2018, to add support for descriptors too.
For now I came up with 2 (imperfect) solutions. One that uses JavaScript to check for a property, like
'ascentOverride' in new FontFace(1,1); // true in Chrome, FF, false in Saf
Not ideal because it's JavaScript.
The other one is to target non-Safari in CSS is with a different property to use as a "proxy". Using the wonderful Compare Browsers feature of CanIUse.com I found a good candidate:
@supports (overflow-anchor: auto) { @font-face { /* works in Chrome, Edge, FF, but not in Safari*/ } }
It's not-ideal to test one thing (overflow-anchor
) and use another (ascent-override
) but at least no JavaScript is involved
Comments? Find me on BlueSky, Mastodon, LinkedIn, Threads, Twitter