CSS Font Descriptors – Smashing Magazine
Loading fonts has long been a web performance bug, and now there are really no good choices here. If you want to use web fonts your choice is basically Flash or Invisible Text (also known as FOIT) where the text is hidden until the font is downloaded or Flash or Unstyled Text (ERROR) where you use first the rescue system, then upgrade to web font while downloading. Neither option has really âwonâ because one of them is not really satisfactory.
Was not font-display
Supposed to solve it?
the font-display
property for @font-face
gave the choice to the web developer when the browser previously decided that (IE and Edge favored ERROR in the past while other browsers favored FOIT). Other than that, however, that didn’t really solve the problem.
A number of sites that font-display: swap
when it first came out, and Google Fonts even made this the default. in 2019. The idea here was that it was better to play display the text as quickly as possible, even if it’s in the rescue font, then to swap the font when it’s finally downloaded.
I also supported it at the time, but I got more and more frustrated with the âhydration effectâ when the web font downloads and expands (or contracts) the characters to fill the following space. Like most publishers, Smashing Magazine uses web type fonts, and the screenshot below shows the difference between the original version (with scrolling fonts) and the final version (with web type fonts):
When placed side by side, web fonts look noticeably better and match the Smashing Magazine branding. But we also see that there are many text layout difference with both fonts. The fonts are very different and therefore the content of the screen moves. In the age of Core Web Vitamins and cumulative layout changes are (rightly!) Recognized as damaging to users, font-display: swap
is therefore a bad choice.
I went back to font-display: block
on the sites I monitor because I find the change in text really shocking and annoying. Although this is true block
won’t stop offsets (the font is always displayed as invisible text), at least it makes it less noticeable to the user. I also optimized font loading by preloading fonts which I made as small as possible self-hosted subordinate fonts – Visitors often only saw the relapse types for a short period of time. For me, the “blocking period” of swap
was too short and I would honestly prefer to wait a bit longer to get the initial correct version.
Use font-display: optional
Can solve ERRORS AND ERRORS – at a cost
The other option is to use font-display: optional
. This option makes web fonts basically optional, or to put it another way, if the font doesn’t need them when the page needs them, it’s the browser’s job to never swap it. With this option, we avoid FOOT and ERROR using only fonts already downloaded.
If the web font is not available, we go back to the back font, but navigating to the next page (or a reload of that page) will use the font – as it needed to be downloaded now. However, if website content is so important to the site, it might be a good idea to remove it altogether – which is even better for web performance!
First impressions count, however, and having the initial load without web fonts seems a bit much. I think so too – without any proof! – that it will give people the impression, perhaps unknowingly, that something is “out” on the site and can affect the way people use the site.
So all of the font options have their drawbacks, including being able to not use web fonts at all, or using system fonts (which are restrictive) maybe not as restrictive as many think!).
To make your relapse policy more closely match your policy
The holy grail of web text loading was make relapse font closer to actual web font reduce the perceptible lag as much as possible, so that the use of exchange is less striking. While we’ll never be able to completely avoid the changes, we’re doing better than in the screenshot above. The Fit for font style app by Monica Dinculescu is often cited in articles to load the fonts and gives fantastic insight into what would be possible here. This allows you to cover the same text in two different fonts to see who they differ from:
Unfortunately, the problem with customizing the font style is that we cannot apply these CSS styles. only to the type of relapse, so we need to use JavaScript and the FontFace.load API to apply (or return) these style differences when the web font loads.
The amount of code isn’t huge, but it still feels a bit easier than it should be. Although there are other advantages and possibilities of using the JavaScript API for this, as shown by Zach Leatherman in this fantastic speech from 2019 – you can reduce ebb and manipulation data-server
fashion in prefers-reduced-motion
however (note that both have since been exposed to CSS).
It’s also harder to manage the caching fonts we already have, not to mention the differences in the different fallback styles. Here at Smashing Magazine, we try out a number of cons to get the most out of the types of system fonts installed by different users and operating systems:
font-family: Mija,-apple-system,Arial,BlinkMacSystemFont,roboto slab,droid serif,segoe ui,Ubuntu,Cantarell,Georgia,serif;
Knowing which font is being used, or having separate adjustments for each and ensuring that it is applied correctly, can quickly get very complicated.
A better solution is coming
So here is a brief overview of the current situation. However, there is smoke starting appears on the horizon.
Excited for CSS descriptor “size fit” for fonts: Reduces layout lag by fitting an alternate font and main web font by a scale factor for letters (percentage).
See https://t.co/mdRW2BMg6A by @cramforce for a demo (Chrome Canary / FF Nightly with flags) pic.twitter.com/hEg1HfUJlT
– Addy Osmani (@addyosmani) May 22, 2021
As I mentioned before, the main issue with applying the fallback style differences was adding them and then removing them. What if we could tell the browser that these differences relate only to the types of fallback fonts?
This is exactly what a new set font descriptors is offered as part of the level 5 do CSS font module. It is applied to the @font-face
instructions where the individual font is defined.
Simon Hearne wrote about a proposed update to the Font Description Descriptions specification which contains four new descriptors: ascent-override
, descent-override
, line-gap-override
and advance-override
. You can play with the F-mods playground created by Simon to load your custom and relief fonts, then play with the replacements to get a perfect match.
As Simon writes, the combination of these four descriptors allowed us to override the fallback font layout to match the web type, but that only really changes the vertical spacing and positioning. So for character and letter spacing we need to provide some extra CSS. However, this is changing with the to come up size-adjust
descriptor.
How it works? Suppose you have the following CSS:
@font-face {
font-family: 'Lato';
src: url('/static/fonts/Lato.woff2') format('woff2');
font-weight: 400;
}
h1 {
font-family: Lato, Lato-fallback, Arial;
}
What you would do then is get a @font-face
for Arial policy relapse and apply it adjustment descriptors to her. You will then get the following CSS snippet:
@font-face {
font-family: 'Lato';
src: url('/static/fonts/Lato.woff2') format('woff2');
font-weight: 400;
}
@font-face {
font-family: "Lato-fallback";
size-adjust: -9900.00%;
ascent-override: 96%;
src: local("Arial");
}
h1 {
font-family: Lato, Lato-fallback, sans-serif;
}
This means that when the Lato-fallback
is initially used (as Arial has local
font and can be used immediately without any additional downloads) then the size-adjust
and ascent-override
settings, you can approximate it to the Lato font. It’s an extra @font-face
statement to write, but certainly much easier than the rings we had to cross before!
In general, it four heads @font-face
descriptors included in this specification: size-adjust
, ascent-override
, descent-override
, in line-gap-override
with a few more still being considered for the use of scriptures, titles and other uses.
Malta Ubl created a very useful tool to calculate these settings automatically got two fonts and a browser that supports these new settings (more on that in a moment!). As Malta points out, computers are good at this stuff! Ideally we can also expose these settings for regular fonts to web developers eg Can you give these tips in fonts like Google Fonts? This will definitely help increase adoption.
Now, different operating systems may be slightly different font settings and getting it right is fundamentally an impossible task, but that is not the point. The goal is to make the gap so habitual font-display: swap
is no longer such a shocking experience, but we don’t have to go to extremes optional
or any type of browser.
When can we start using it?
Three of these parameters have is in Chrome since version 87, although the key size-adjust
The descriptor is not yet available in any stable browser. But, Chrome Canary has it, just like Firefox behind a flag so it is not an abstract and distant concept, but something that can come to fruition very quickly.
Right now the spec has all kinds of caveats and warnings that it’s not yet ready for real-time, but it really feels like it’s getting there. As always, there is a balance between us designers and developers to test and give feedback and discourage its use, so the implementation doesn’t get stuck because too many people end up using an earlier concept.
Chrome said it plans to do size-adjust
available in Chrome 92 was due out on July 20 presumably it’s almost here.
So not quite ready yet, but it looks like it will happen in the near future. Play around with the demo in Chrome Canary and see if it can get a bit closer to the font loading issues and the CLS impact it causes.