This is an incidental annoyance, but I have to ask somewhere: why have we decided that the FOUC (“flash of unstyled content”) caused by laying out the page twice, once without and once with the fonts, is such a dire problem that it’s worth blocking the page’s first usable render behind a ~1MB resource? If memory serves, that decision is from before the twilight of the Web of documents, a time when div soup and inline styles (now replaced by Tailwind) were widely frowned upon.
Why is it OK to leave a user on a slow or high-latency connection staring at a blank skeleton of a page, as though written in invisible ink, for several seconds? I still remember using Opera because it had a toggle for “cached images only”. What happened?
> why have we decided that the FOUC (“flash of unstyled content”) ... is such a dire problem
I think the answer is that different people are sensitive to different things. I'll often come across articles going to great length to reduce some minor jank in animations or page load, and I'll be looking at it thinking yeah, I can see it, but it really doesn't bother me enough to fix. Certainly not by going to these lengths.
Meanwhile, FOUC bothers me a lot, to the point where I can't understand that its accepted in any form. I'd much rather that I don't get shown the page at all until the real font is loaded. Otherwise my eye will have tracked to the text, started reading and then there's a jarring reflow and I lose my place and have to find it again. If I'm scanning for information through lots of websites, it does mentally tire me.
I think there are different use cases, though; like, I agree with you that I find it really really annoying when I'm starting to read a paragraph of text... but, for the various buttons and navigation structure--even the headings--having them temporarily in the wrong font is a major win, as it lets me start to orient myself into the page (and might even help me get to my next nav point and out of the site before the font even bothers to load).
> why have we decided that the FOUC (“flash of unstyled content”) caused by laying out the page twice, once without and once with the fonts, is such a dire problem that it’s worth blocking the page’s first usable render behind a ~1MB resource?
Why do you think that's a majority view? Google's page speed metric which they use as a SEO signal is followed by many webdevs and it very strongly encourages displaying text with system fonts while custom fonts load, and that the top of the page is displayed quickly:
"Ensure text remains visible during webfont load ... Fonts are often large files with slow load times. Some browsers hide text until the font loads, causing a flash of invisible text (FOIT)."
"First Contentful Paint (FCP) is an important, user-centric metric for measuring perceived load speed because it marks the first point in the page load timeline where the user can see anything on the screen—a fast FCP helps reassure the user that something is happening."
If you hide the page content from displaying until custom fonts load and your header image loads for example, you'll likely get a red/unacceptable score.
Yea but the same POS company then tells you CLS bad mkaaaay... and guess what FOUC causes, layout shifts... (sorry, I got carried away with all the acronyms haha)
> tells you CLS bad mkaaaay... and guess what FOUC causes, layout shifts
I haven't had a problem here (with layout shift). As long as you specify width + height of images in the HTML, and you don't have dynamic content pushing the layout about as it loads it in your page header, you'll likely get a high CLS score as it has some leeway.
And sounds like `font-size-adjust` from the OP is helpful in avoiding layout shift when the stand-in font is swapped out for the custom font when it arrives? I haven't found this necessary though.
I don’t have extensive experience on this yet, but I believe this is also a solved issue (using custom fonts). Serve the font-family from the same source as the website, preload only the primary font-style (say “normal”), and custom-pick the font to just the Latin subset. That should be fast enough that almost none will notice, except for the pedantic developers like us (personally, I can forgive that).
Henceforth, let the others (styles, variable, etc) kick in as needed.
You can also subset your fonts; e.g. if your content is in a language that uses the Latin alphabet, then you only need to include those characters in your font. Between that, variable fonts, and WOFF2, I've managed to get Inter down to 50kB (plus another 50 if you need real italics).
Partly, the answer is “tough”. As a designer, you don’t and aren’t meant to have pixel-level control over the screen contents. Web is not print. Don’t ask for the PostScript standard fourteen. (Somehow this lesson comes through much better for reflowable ebooks.)
Partly, I am willing to admit that web fonts are still nice when you can get them. But they’re too unwieldy to block on (slow connections exist; font foundries are assholes[1]; etc.), and we don’t really have a solution (the problem with FOUC is not the unstyled content, it’s the layout shift).
While I'm absolutely not a design-should-rule-all person, I think there's quite a range between "pixel-level control" and "you can't choose which font to use".
If we'd reliably have the top 50 google fonts on every OS, there'd be a lot less webfonts used.
system-ui
Glyphs are taken from the default user interface font
on a given platform. Because typographic traditions vary
widely across the world, this generic is provided for
typefaces that don't map cleanly into the other generics.
Leaving the page blank isn’t the solution but if you want to blame anyone blame Google. Everyone chases their web best practices that Google can’t even be bothered to follow. Maybe with ai killing search we can get back to building sites the right way.
I’d take this further: why have we decided that it’s acceptable to require a megabyte to be able to display the styled content at all? If custom fonts cause a major delay, don’t use them.
To clarify, "specify @font-face inline" meant to say that the font's URL should be in the `head`, not the actual font bytes. The linked page includes `<link href="/fonts/GeistVF.woff2" rel="preload" type="font/woff2" as="font" crossorigin="">` in the `head`, which is another (probably better) way to achieve "font URL in the head" outcome.
But I must say I don't agree with `font-display: optional` advice. It indeed maximize the LCP and CLS metrics, but it does that to the extent that the results become detrimental to the user experience. Like, if I open that link in a private window, and then hit refresh, the layout shifts, because I don't have their custom font on the first load, but do have it on the second one. This doesn't make sense! Do you want me to see your custom font or not?
I would say that if you _really_ care about the page being ready as fast as possible, you should use `font-style: system-ui`. If you _really_ care about your fonts, you should use `font-display: auto` or `font-display: block` (and, yes, tweak fallback font metrics). If you care about _both_, tough luck, they are inherently in conflict and you need to pick one side. `font-display: optional` let's you formally pass the automated test with flying colors, but doesn't seem to result in actually useful behavior?
Oh wow. I love this. I think this is precisely what I’ve needed when I want to use fonts and emojis as icons in my toy games but they’re just never consistent.
Monospaced fonts always bother me when I use them in emails or on websites. Never the same size as the prose. This is great for websites at least! Wonder if I could find an HTML mode to use in Thunderbird and if any email client would understand this css directive
That adjusts leading (from the material originally used, so rhymes with "breading") and thus space between lines.
This adjusts properties such as x- and cap heights, which determine relative proportions of characters within the line. For example, in a browser supporting font-size-adjust, any font can be used as small caps.
(2023) and it is worth noting that web typography is painfully rudimentary, as even a quick skim of Bringhurst's Elements of Typographic Style suffices to demonstrate. I would strongly recommend the purchase of a physical copy to anyone in or aspiring to design; you will make far more beautiful text just for having read it, which I think you will also enjoy (I have and do!), and it is a handsome artifact besides.
Font designers intentionally decided to define things based on the size of that box, rather than the size of the x, right? I bet they did that for a reason.
I believe the bounding box has to fit all the possible ascenders and descenders etc., so the em-height is proportioned within the box to whatever the highest and lowest marks in the typeface are.
But this technique isn’t correcting for some kind of mistake the typographer theoretically made, it’s adjusting for the fact that CSS sizes by the bounding box instead of the em-height. The font itself is unchanged and renders exactly how it’s designed, this just lets us use it in a more intuitive way.
IMO sizing by bounding-box was the wrong move in the original CSS spec, but that’s how digital type renderers have worked going back to the eighties, so the whole thing was probably too entrenched in the first place. And I have no idea if font standards of the day even had em-heights encoded in a way that could be read in font metadata.
Anyway, this whole feature is news to me, can’t wait to try it. Between this and text-box-trim (life changing), I’ve never been happier with web design.
> I believe the bounding box has to fit all the possible ascenders and descenders etc., so the em-height is proportioned within the box to whatever the highest and lowest marks in the typeface are.
I wish it were this simple.
The em square != the bounding box of all glyphs. The em square is defined by the font's ascent & descent vertical metrics, which are set by the font designer.
There are reasons why you might want glyphs to escape the em square. Perhaps you're typesetting English text without accent marks above capitals, and using the bounding box's vertical maximum would introduce too much line space. Or perhaps you're using a decorative font which is designed to escape the em square, and potentially even overlap the em squares of lines above and below, like this: https://alangrow.com/images/blog/script-font-escaping-em-squ...
To make matters worse, and mostly for legacy reasons, there are THREE different sets of ascent & descent metrics in a font file. Which is used depends on your OS and the software rendering the font. But the Webfont Strategy described here is a nice one, because you can use the bounding box (winAscent & winDescent) if you really need to, say because any glyph might be used and you want to avoid em square escape: https://glyphsapp.com/learn/vertical-metrics
Font files are based on the original “font”, which was a drawer of metal type. Metal type size was based on the full piece of metal which was sized based on the full extent of the typeface, including capitals, ascenders and descenders. When typesetting went digital it made sense to continue with this approach since the industry needed a plug-n-play way to use digital assets; that is, a typesetter could use the same concepts and language that existed for physical type as well.
As a long time print and digital designer I’m very excited to have these new type tools that meet the needs of digital typesetting on the web!
Font size being the bounding box means that you can determine the line height from just the font size with no knowledge of the font itself, which makes layout simpler. This was significant in the 80s when the convention was established, but probably isn't today in the context of the dramatically more complicated CSS layout engines.
Is there a way to make the text fill the box in 1 line? So short text shows with a bigger font and longer text shows with a smaller font. The only way I found was multiple passes with javascript.
Is there is a way to automatically tell HTML/CSS to adjust the font size automatically? For example, iOS UILabel has adjustsFontSizeToFitWidth. Does HTML have anything similar?
I don’t believe so. It would be hugely useful, but I have found the iOS implementation to be kind of wonky, so I’d rather it not come to web unless the idea can be perfected.
Also I think a proper implementation would require reference to line count in the CSS markup, and CSS seems to have an awful time with properties that depend on character or line counts. We still don’t have working line-clamp!
ex.
div {
font-size: 24px;
}
div[line-count > 2] { // doesn’t exist, and must be difficult to implement
font-size: fit-width; // … what about vertical text?
min-font-size: 8px; // maintain legibility
max-font-size: 28px; // why not
}
Sure would make a lot of my designers happy, though…
My hot take is that browsers should never have enabled you to specify an exact font. The web would be much better off if it was accepted that the server could only suggest how the content is displayed, not control it.
This works when users broadly understand the concept of a user agent, which has not ever really been the case in the general sense, and indeed we observe a historical trend toward increase in the conceptual distance between usership and agency.
Your hot take reduces to that the web should never have become a product, which is equally defensible and in my view the formulation more likely productive of interestingly nuanced discussion. For example, we could critique the Gopher and Gemini crowds' sort of conceptually Sapir-Whorf-esque approach to at least notional redress, or ask what effect clientside inference might come to have.
I think the reason most people dont consider font-adjust useful, is if you are explicitly chosing fonts you are going to chose ones with compatible metrics.
That is hard to do in my experience, when only using free fonts. I'm wondering if this works on icon fonts, which are not fun to deal with when they don't align correctly.
This is an incidental annoyance, but I have to ask somewhere: why have we decided that the FOUC (“flash of unstyled content”) caused by laying out the page twice, once without and once with the fonts, is such a dire problem that it’s worth blocking the page’s first usable render behind a ~1MB resource? If memory serves, that decision is from before the twilight of the Web of documents, a time when div soup and inline styles (now replaced by Tailwind) were widely frowned upon.
Why is it OK to leave a user on a slow or high-latency connection staring at a blank skeleton of a page, as though written in invisible ink, for several seconds? I still remember using Opera because it had a toggle for “cached images only”. What happened?
> why have we decided that the FOUC (“flash of unstyled content”) ... is such a dire problem
I think the answer is that different people are sensitive to different things. I'll often come across articles going to great length to reduce some minor jank in animations or page load, and I'll be looking at it thinking yeah, I can see it, but it really doesn't bother me enough to fix. Certainly not by going to these lengths.
Meanwhile, FOUC bothers me a lot, to the point where I can't understand that its accepted in any form. I'd much rather that I don't get shown the page at all until the real font is loaded. Otherwise my eye will have tracked to the text, started reading and then there's a jarring reflow and I lose my place and have to find it again. If I'm scanning for information through lots of websites, it does mentally tire me.
Based on all this is does seem like there's a 'missing' option to only swap the fonts when they’re off-screen, which avoids:
1. blocking first-paint 2. 'flashes' of anything 3. Not showing the font at all.
A quick mockup: https://codepen.io/pjwdev/pen/ByoLJoR
(This is an intentionally bad fallback. If it were Georgia the effect would be a whole lot more subtle.)
I think there are different use cases, though; like, I agree with you that I find it really really annoying when I'm starting to read a paragraph of text... but, for the various buttons and navigation structure--even the headings--having them temporarily in the wrong font is a major win, as it lets me start to orient myself into the page (and might even help me get to my next nav point and out of the site before the font even bothers to load).
> why have we decided that the FOUC (“flash of unstyled content”) caused by laying out the page twice, once without and once with the fonts, is such a dire problem that it’s worth blocking the page’s first usable render behind a ~1MB resource?
Why do you think that's a majority view? Google's page speed metric which they use as a SEO signal is followed by many webdevs and it very strongly encourages displaying text with system fonts while custom fonts load, and that the top of the page is displayed quickly:
"Ensure text remains visible during webfont load ... Fonts are often large files with slow load times. Some browsers hide text until the font loads, causing a flash of invisible text (FOIT)."
https://developer.chrome.com/docs/lighthouse/performance/fon...
"First Contentful Paint (FCP) is an important, user-centric metric for measuring perceived load speed because it marks the first point in the page load timeline where the user can see anything on the screen—a fast FCP helps reassure the user that something is happening."
https://web.dev/articles/fcp
If you hide the page content from displaying until custom fonts load and your header image loads for example, you'll likely get a red/unacceptable score.
Yea but the same POS company then tells you CLS bad mkaaaay... and guess what FOUC causes, layout shifts... (sorry, I got carried away with all the acronyms haha)
> tells you CLS bad mkaaaay... and guess what FOUC causes, layout shifts
I haven't had a problem here (with layout shift). As long as you specify width + height of images in the HTML, and you don't have dynamic content pushing the layout about as it loads it in your page header, you'll likely get a high CLS score as it has some leeway.
And sounds like `font-size-adjust` from the OP is helpful in avoiding layout shift when the stand-in font is swapped out for the custom font when it arrives? I haven't found this necessary though.
I think the best solution for this is to just not use webfonts, and in fact use the system font instead.
I don’t have extensive experience on this yet, but I believe this is also a solved issue (using custom fonts). Serve the font-family from the same source as the website, preload only the primary font-style (say “normal”), and custom-pick the font to just the Latin subset. That should be fast enough that almost none will notice, except for the pedantic developers like us (personally, I can forgive that).
Henceforth, let the others (styles, variable, etc) kick in as needed.
Yep, that's what I do on my website (except for the Latin subset). Still noticeable on spotty connections, like on a phone in a dead zone.
Or just use any of the font stacks from https://modernfontstacks.com/
I like custom fonts, but I must say I like this. Will use it on my blog.
You can also subset your fonts; e.g. if your content is in a language that uses the Latin alphabet, then you only need to include those characters in your font. Between that, variable fonts, and WOFF2, I've managed to get Inter down to 50kB (plus another 50 if you need real italics).
I get Inter at 77kb but that includes 8 language versions of the site... or should it be less?
Which system font? There’s no standards here; each operating system has their own, with no guarantees as to what is available.
Until OS developers get their house in order, designers will keep on ignoring them.
Partly, the answer is “tough”. As a designer, you don’t and aren’t meant to have pixel-level control over the screen contents. Web is not print. Don’t ask for the PostScript standard fourteen. (Somehow this lesson comes through much better for reflowable ebooks.)
Partly, I am willing to admit that web fonts are still nice when you can get them. But they’re too unwieldy to block on (slow connections exist; font foundries are assholes[1]; etc.), and we don’t really have a solution (the problem with FOUC is not the unstyled content, it’s the layout shift).
[1] https://jakearchibald.com/2021/f1-perf-part-1/
While I'm absolutely not a design-should-rule-all person, I think there's quite a range between "pixel-level control" and "you can't choose which font to use".
If we'd reliably have the top 50 google fonts on every OS, there'd be a lot less webfonts used.
From https://developer.mozilla.org/en-US/docs/Web/CSS/font-family :
Which system font? There’s no standards here;
Yes, there is:
Just brainstorming here, why can't we have "browser fonts" shipped with the browsers?
There's serif, sans-serif, monospace,... That's more than enough to present any content.
Even better: we have OS fonts shipped with the OS, also users can install additional fonts for all the applications to use.
Leaving the page blank isn’t the solution but if you want to blame anyone blame Google. Everyone chases their web best practices that Google can’t even be bothered to follow. Maybe with ai killing search we can get back to building sites the right way.
I’d take this further: why have we decided that it’s acceptable to require a megabyte to be able to display the styled content at all? If custom fonts cause a major delay, don’t use them.
Why invisible link? You can display a fallback font when your main one is loading
>(now replaced by Tailwind)
Speak for yourself. Tailwind isn't universal.
Please don’t inline a whole font to avoid a momentary flash. You’re worsening every page’s load to avoid a stutter on one.
Here’s what is still the authority on this https://www.industrialempathy.com/posts/high-performance-web...
To clarify, "specify @font-face inline" meant to say that the font's URL should be in the `head`, not the actual font bytes. The linked page includes `<link href="/fonts/GeistVF.woff2" rel="preload" type="font/woff2" as="font" crossorigin="">` in the `head`, which is another (probably better) way to achieve "font URL in the head" outcome.
But I must say I don't agree with `font-display: optional` advice. It indeed maximize the LCP and CLS metrics, but it does that to the extent that the results become detrimental to the user experience. Like, if I open that link in a private window, and then hit refresh, the layout shifts, because I don't have their custom font on the first load, but do have it on the second one. This doesn't make sense! Do you want me to see your custom font or not?
I would say that if you _really_ care about the page being ready as fast as possible, you should use `font-style: system-ui`. If you _really_ care about your fonts, you should use `font-display: auto` or `font-display: block` (and, yes, tweak fallback font metrics). If you care about _both_, tough luck, they are inherently in conflict and you need to pick one side. `font-display: optional` let's you formally pass the automated test with flying colors, but doesn't seem to result in actually useful behavior?
Oh wow. I love this. I think this is precisely what I’ve needed when I want to use fonts and emojis as icons in my toy games but they’re just never consistent.
That is a great use case! More compelling than the original blog post I think.
Monospaced fonts always bother me when I use them in emails or on websites. Never the same size as the prose. This is great for websites at least! Wonder if I could find an HTML mode to use in Thunderbird and if any email client would understand this css directive
Text-Box
I’m probably missing the obvious but how is font-size-adjust different from text-box-trim.
https://github.com/jantimon/text-box-trim-examples
That adjusts leading (from the material originally used, so rhymes with "breading") and thus space between lines.
This adjusts properties such as x- and cap heights, which determine relative proportions of characters within the line. For example, in a browser supporting font-size-adjust, any font can be used as small caps.
I wrote a quick note on that:
Leading or Line Height - a Measured Response
https://untested.sonnet.io/notes/leading-or-line-height-a-me...
(2023) and it is worth noting that web typography is painfully rudimentary, as even a quick skim of Bringhurst's Elements of Typographic Style suffices to demonstrate. I would strongly recommend the purchase of a physical copy to anyone in or aspiring to design; you will make far more beautiful text just for having read it, which I think you will also enjoy (I have and do!), and it is a handsome artifact besides.
Font designers intentionally decided to define things based on the size of that box, rather than the size of the x, right? I bet they did that for a reason.
I believe the bounding box has to fit all the possible ascenders and descenders etc., so the em-height is proportioned within the box to whatever the highest and lowest marks in the typeface are.
But this technique isn’t correcting for some kind of mistake the typographer theoretically made, it’s adjusting for the fact that CSS sizes by the bounding box instead of the em-height. The font itself is unchanged and renders exactly how it’s designed, this just lets us use it in a more intuitive way.
IMO sizing by bounding-box was the wrong move in the original CSS spec, but that’s how digital type renderers have worked going back to the eighties, so the whole thing was probably too entrenched in the first place. And I have no idea if font standards of the day even had em-heights encoded in a way that could be read in font metadata.
Anyway, this whole feature is news to me, can’t wait to try it. Between this and text-box-trim (life changing), I’ve never been happier with web design.
> I believe the bounding box has to fit all the possible ascenders and descenders etc., so the em-height is proportioned within the box to whatever the highest and lowest marks in the typeface are.
I wish it were this simple.
The em square != the bounding box of all glyphs. The em square is defined by the font's ascent & descent vertical metrics, which are set by the font designer.
There are reasons why you might want glyphs to escape the em square. Perhaps you're typesetting English text without accent marks above capitals, and using the bounding box's vertical maximum would introduce too much line space. Or perhaps you're using a decorative font which is designed to escape the em square, and potentially even overlap the em squares of lines above and below, like this: https://alangrow.com/images/blog/script-font-escaping-em-squ...
To make matters worse, and mostly for legacy reasons, there are THREE different sets of ascent & descent metrics in a font file. Which is used depends on your OS and the software rendering the font. But the Webfont Strategy described here is a nice one, because you can use the bounding box (winAscent & winDescent) if you really need to, say because any glyph might be used and you want to avoid em square escape: https://glyphsapp.com/learn/vertical-metrics
Font files are based on the original “font”, which was a drawer of metal type. Metal type size was based on the full piece of metal which was sized based on the full extent of the typeface, including capitals, ascenders and descenders. When typesetting went digital it made sense to continue with this approach since the industry needed a plug-n-play way to use digital assets; that is, a typesetter could use the same concepts and language that existed for physical type as well.
As a long time print and digital designer I’m very excited to have these new type tools that meet the needs of digital typesetting on the web!
Font size being the bounding box means that you can determine the line height from just the font size with no knowledge of the font itself, which makes layout simpler. This was significant in the 80s when the convention was established, but probably isn't today in the context of the dramatically more complicated CSS layout engines.
Those sound like the exact same use case in the end as both are concerned with what happens to the texture of a page were the font to change.
Is there a way to make the text fill the box in 1 line? So short text shows with a bigger font and longer text shows with a smaller font. The only way I found was multiple passes with javascript.
I think there is a hack you can do with scroll driven animation https://frontendmasters.com/blog/edge-to-edge-text/
Is there is a way to automatically tell HTML/CSS to adjust the font size automatically? For example, iOS UILabel has adjustsFontSizeToFitWidth. Does HTML have anything similar?
I don’t believe so. It would be hugely useful, but I have found the iOS implementation to be kind of wonky, so I’d rather it not come to web unless the idea can be perfected.
Also I think a proper implementation would require reference to line count in the CSS markup, and CSS seems to have an awful time with properties that depend on character or line counts. We still don’t have working line-clamp!
ex.
Sure would make a lot of my designers happy, though…My hot take is that browsers should never have enabled you to specify an exact font. The web would be much better off if it was accepted that the server could only suggest how the content is displayed, not control it.
This works when users broadly understand the concept of a user agent, which has not ever really been the case in the general sense, and indeed we observe a historical trend toward increase in the conceptual distance between usership and agency.
Your hot take reduces to that the web should never have become a product, which is equally defensible and in my view the formulation more likely productive of interestingly nuanced discussion. For example, we could critique the Gopher and Gemini crowds' sort of conceptually Sapir-Whorf-esque approach to at least notional redress, or ask what effect clientside inference might come to have.
That’s how it was for over a decade, with the browser quirks and inconsistent behavior. Why is that good?
I think the reason most people dont consider font-adjust useful, is if you are explicitly chosing fonts you are going to chose ones with compatible metrics.
I think the argument you may change the fonts in the future presented in the article a great counterpoint.
You can ensure the size won’t change even in the future with a font that hasn’t even been designed yet.
That’s a nice benefit.
That is hard to do in my experience, when only using free fonts. I'm wondering if this works on icon fonts, which are not fun to deal with when they don't align correctly.