top | item 30129571

How to avoid layout shifts caused by web fonts

192 points| joshbetz | 4 years ago |simonhearne.com | reply

121 comments

order
[+] divbzero|4 years ago|reply
The suggestion I like the most is 3.4) Use system fonts:

  body {
    font-family: -apple-system, BlinkMacSystemFont,
      "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell",
      "Fira Sans", "Droid Sans", "Helvetica Neue",
      sans-serif;
  }
Stack Overflow took this approach last year with the following font stack: [1]

  @ff-sans:
    system-ui, -apple-system, BlinkMacSystemFont, // San Francisco on macOS and iOS
    "Segoe UI", // Windows
    "Ubuntu", // Ubuntu
    "Roboto", "Noto Sans", "Droid Sans", // Chrome OS and Android with fallbacks
    sans-serif; // The final fallback for rendering in sans-serif.
  @ff-serif: Georgia, Cambria, "Times New Roman", Times, serif;
  @ff-mono:
    ui-monospace, // San Francisco Mono on macOS and iOS
    "Cascadia Mono", "Segoe UI Mono", // Newer Windows monospace fonts that are optionally installed. Most likely to be rendered in Consolas
    "Ubuntu Mono", // Ubuntu
    "Roboto Mono", // Chrome OS and Android
    Menlo, Monaco, Consolas, // A few sensible system font choices
    monospace; // The final fallback for rendering in monospace.
[1]: https://meta.stackexchange.com/questions/364048/we-are-switc...
[+] chrismorgan|4 years ago|reply
-apple-system and BlinkMacSystemFont are now both obsolete and covered by system-ui. Almost all of the named fonts in common font stacks are either now superfluous or not a good idea any more, causing more harm than they solve.

For sans-serif, I recommend at most three items: a web font, system-ui, and sans-serif. No more. I would note that system-ui is not necessarily sans-serif, but in practice it almost always is, and ui-sans-serif (along with ui-serif, ui-monospace and ui-rounded) is only implemented by Safari yet.

For serif, I recommend at most three items, possibly including one named font: a web font, Georgia, and serif. See, serif is probably a narrower serif (something like Times New Roman), but Georgia a wider one—they’re fairly different in character, so that it can be worth including if you’re doing so deliberately.

For monospace, I recommend at most four: a web font, ui-monospace (I wouldn’t, but some macOS people prefer it), Consolas, and monospace. I think Consolas is worth keeping in until Firefox updates its Windows default (https://bugzilla.mozilla.org/show_bug.cgi?id=713680), because Courier New is that bad.

Most font stacks now are just cargo culting, and are mostly mildly harmful.

[+] thrdbndndn|4 years ago|reply
>Stack Overflow took this approach last year

Just to note, what you posted below isn't their final version, and for good reasons. Anyone that is interested about this please check the original post with update 1,2, and 3.

On the other hand, I still failed to see the the advantage of such complex stack vs

    font-family: sans-serif;
Why reinvent the wheel when you can just use this and it would use browser's default sans-serif font setting? Which users can define to whatever they want, system font or not.
[+] bruce343434|4 years ago|reply
Why not just `body {font-family: sans-serif}`? Like, you don't have to explicitly enumerate all sans-serif system fonts ever. The browser will handle it.
[+] TacticalCoder|4 years ago|reply
The typical font stacks IMO always forget to put "Liberation". For many Linux desktop users it's going to be the best available when Oxygen/Cantarell/Ubuntu aren't there. Many Debian users, for example, are going to have Liberation and not the others. It's sad that a fugly default is often going to be picked up for these users instead of Liberation.

So: modern font stacks... Not bad, but not yet the panacea either (even for big websites who really should know better).

[+] city41|4 years ago|reply
I am a firm believer in this and just using built in fonts in general. Users really don't care about fonts, they really don't. And if you really need a specific font for say a logo, use an SVG with the text converted to paths. But of course only do that in image type situations and provide alt text.
[+] wakeupcall|4 years ago|reply
I just disable webfonts by default myself. I wonder how common that is. I never felt that I missed anything, because let's face it: in 99% of the cases you jump on a website through search and leave it within 60 seconds.

I make exceptions for websites that I visit regularly, where the most frequent breakage is a custom font that packs icons. On websites that I frequently read for documentation I sometimes even swap the font to something that I prefer (by injecting a @font-face src:local rule).

Designer's choice of fonts are frequently lower in legibility and/or do not have good hinting (not at the same level of most system fonts). On non-retina displays the qualitative difference is sometimes staggering.

[+] vladvasiliu|4 years ago|reply
> Designer's choice of fonts are frequently lower in legibility and/or do not have good hinting (not at the same level of most system fonts). On non-retina displays the qualitative difference is sometimes staggering.

This. Plus sometimes, for some reason, they choose hair-thin versions of fonts that are a pain to read even on (non mac) retina displays.

[+] mattbee|4 years ago|reply
He forgot one: inline the font data (evil cackle).

This made sense for me in conjunction with subsetting for a stopwatch app that only needs 10 digits and a colon.

I submit it's not so bad if you inline it with the rest of your styling, at least that's cacheable separate from the content.

[+] lelandfe|4 years ago|reply
I’ve been meaning to build a PoC where you subset to the glyphs shown above the fold, inline, and then download the full font face at a low priority.
[+] jurnalanas|4 years ago|reply
You can use a library to take care a lot of FOUT versus FOIT experience. Face Observer (https://fontfaceobserver.com) lets you wait for the web fonts to load, then responds accordingly.

    var html = document.documentElement;
    var script = document.createElement("script");
    script.src = "fontfaceobserver.js";
    script.async = true;

    script.onload = function () {
      var roboto = new FontFaceObserver("Roboto");
      var sansita = new FontFaceObserver("Sansita");
      var timeout = 2000;

      Promise.all([
        roboto.load(null, timeout),
        sansita.load(null, timeout)
      ]).then(function () {
        html.classList.add("fonts-loaded");
      }).catch(function (e) {
        html.classList.add("fonts-failed");
      });
    };
    document.head.appendChild(script);
[+] account42|4 years ago|reply
If you do this please make sure to not hide things when scripts are disabled.
[+] KronisLV|4 years ago|reply
> Downloading one or two font files to render text won’t have a massive impact on speed, downloading five or ten font files will!

I wonder why we almost never talk about the actual filesizes of different fonts and which ones take less space, for when the total size of our webpages is important and we'd like to make our font choices with that in mind, provided that we don't want to just use the system fonts for whatever reason.

For example, i described some of the specifics of serving my own fonts on my site instead of using Google Fonts in a discussion about privacy some time back: https://news.ycombinator.com/item?id=29996364

The question that i posed in that comment still hasn't really been answered and is still relevant in my eyes:

> While we're on the topic of fonts, it's a shame that we don't think more about how heavy the fonts we choose to use are, since right now serving my own fonts eats up around half of the bandwidth on my non-image-heavy site. The single article that i've found on the topic so far as been this, "Smallest (file size) Google Web Fonts": http://www.oxfordshireweb.com/smallest-file-size-google-web-...

Why doesn't Google Fonts have a field somewhere that'd show the total size of a font in any number of supported file formats? Why do we have so much effort towards optimizing the sizes of images, and yet fonts don't get the same love?

[+] Aeolun|4 years ago|reply
Heh, if I serve custom Japanese fonts we happily go into the megabyte range.
[+] nicbou|4 years ago|reply
Fonts on my website add up to around 40kb. It barely makes a difference.
[+] lelandfe|4 years ago|reply
> Preloaded fonts delay main JS bundle

Am I crazy or does that waterfall pretty clearly show nothing of the sort? When using http/2, a reasonable amount of preloaded assets won’t block anything else in the critical path…

[+] cblconfederate|4 years ago|reply
Just use system fonts. Except on android, it's only roboto

And do use verdana, it's the most readable font. Admit it, you like it here

[+] hawski|4 years ago|reply
How to avoid layout shifts caused by CSS loading.

How to avoid layout shifts caused by images.

How to avoid layout shifts caused by ads.

How to avoid layout shifts caused by DOM changes.

It is funny how as many things moved to web we still have those basic issues, that would be considered show stopper errors in a desktop app.

Sometimes I would like for the browser to keep the state from 0.2 second ago when I decided to tap or click and do something like nothing did change in this time.

[+] dmitryminkovsky|4 years ago|reply
> How to avoid layout shifts caused by images.

And it’s funny how the state of the art way to address these issues is usually some absurd hack. Like in the case of images, setting the height to 0 and using padding to achieve a stable height: https://nikitahl.com/css-aspect-ratio.

[+] 41b696ef1113|4 years ago|reply
>How to avoid layout shifts caused by ads.

Not sure this one counts as a bug, but a deliberate WONTFIX. I never intentionally click on ads, but I have been known to press one when an ad "happened" to appear in the position of some other content.

[+] logifail|4 years ago|reply
With the default settings I find this web page almost impossible to read (with my glasses on). The font is [too] small and the contrast is poor.

"Avoiding layout shifts caused by web fonts" is a great topic.

"Readability" would be another one.

[+] tacone|4 years ago|reply
If OS makers reached some kind of agreement to incorporate the most used 20 web fonts in their OS, 99% of this madness would be gone.
[+] Macha|4 years ago|reply
This was pretty much done with the original web safe fonts, but fonts have an element of fashion to it and moved on and pretty much all of them are seen as dated by the people who do specifically pick fonts.
[+] cblconfederate|4 years ago|reply
And use the same 120 fonts in our website? What are we, plebs? Plz download this 45mb font that we made this morning
[+] jesprenj|4 years ago|reply
Ironically, this website's heading shifted it's layout after the new font loaded (:
[+] donatj|4 years ago|reply
1. Don’t use web fonts.

2. There is no step 2

They just slow the web down and often make things less legible in the name of style.

[+] togaen|4 years ago|reply
Easy: don’t use them. They are a waste of time anyway. I promise you your users care 0% about whether your font is “just right” or not.
[+] NaughtyShiba|4 years ago|reply
It’s not about “just right”. It’s about branding.
[+] distantsounds|4 years ago|reply
Until the HTML spec is actually fixed so this isn't a problem solved by jabascript/css hacks, this is the accurate answer
[+] tomcooks|4 years ago|reply
> Most designers will cringe at the thought of showing users a fallback system font.

Explaining them that web is not paper, helps removing a lot of this childish behaviour.

[+] l0b0|4 years ago|reply
I guess it's a good thing the web is built for users rather than designers, then, isn't it? Oh wait.

On a more serious note, screw all the font **ery. Settings → Language and Appearance → Advanced → untick Allow pages to choose their own fonts, instead of your selections above. Better to have some crappy websites glitch out a bit than get a headache from trying to read 200 different fonts in a day.

[+] rtpg|4 years ago|reply
I do think that sites should strive to "just work" with nice system fonts (and respect user agent settings), but this is just an obtuse answer.

You can ship your own fonts. Everyone and their dog uses one of two web browser engines. People want their websites to "look right". You can offer a fully specified look!

[+] Raed667|4 years ago|reply
Designers want the web-app to look like their figma. Most are not willing to compromise on that.

It takes senior engineers (with weight in the company) to lead the effort to force design to concede on certain things like this.

[+] lelandfe|4 years ago|reply
And for that matter, let’s put the kibosh on the childish act of using colors as well
[+] deanc|4 years ago|reply
Except it doesn't. The usual fallback I've experienced (been told to do) to this is to preload the whole site behind a loading bar instead :)
[+] mrweasel|4 years ago|reply
I’m sure there’s a few exception, but why do anyone care about which font is used as long as the basics such as fixed or sans serif is applied correctly?

The answer is most likely branding, but I don’t recall landing on a company website and going: “That’s not the font from their design guidelines. This is unacceptable, I shall take my business elsewhere”

All this tweaking and hacking font loading is a vaste of time.

[+] 2Gkashmiri|4 years ago|reply
i have tried to ask people a simple question. "why do you think you know fonts better than microsoft or apple?" not to even talk about linux for a moment here. do these multi trillion dollar companies making operating systems do a shit job at fonts that each and every website developer needs to use google fonts that increase dependency on third parties than using system default fonts?