🏄🏽 Font Swap CLS #
In this post, we see how you can use SvelteKit with Fontaine to reduce Cumulative Layout Shift (CLS) by up to 100%, when working with custom or self-hosted fonts. We first look at how the problem arises, then turn to a solution, using Fontaine. If that’s what you came here for, then let’s roll our sleeves up!
We focus on SvelteKit here, and use Fontaine to solve the problem. Our solution relies on Vite support, so the same approach should work just fine with Astro, for example. Though if you are working with Astro, or want to know how Fontaine works under the hood, see the recent article on reducing Astro font swap CLS using Capsize.
🤔 Problem: Ensuring Text Remains Visible during Webfont Load #
When running Lighthouse web development tooling, if your site uses webfonts or Google fonts, you might get the suggestion: “Ensure text remains visible during webfont load”. This is because text might well be invisible, on a slow connection, while the browser loads the webfont. Somehow making the text visible, even in a font other than the preferred one, will improve user experience, making the page appear to load quicker.
🫣 Solution: Set font‑display: swap
#
The advice offered on the Chrome Developers site, to ensure the font remains visible, is to use the @font-face
font-display: swap
directive . Browsers will have some fonts available by default. Typically, Times New Roman and Arial are
included in this list, though for Android devices, Roboto is your safe default.
Setting the font-display: swap
directive instructs the browser to display
the fallback font, instead of the webfont, whenever the webfont is not available quickly. Then, once
the webfont has fully downloaded the browser swaps out the fallback font with the webfont. Typically,
you will set Arial as the fallback for sans fonts and Times New Roman for serif. Then, include Roboto
as a second fallback for both (serif and sans-serif), to cover Android devices.
😬 New Problem: Font Swap introduces Layout Shift #
Our approach improves user experience, making the page load faster. However, it introduces a side
effect: layout shift. Fonts have different metrics — the height of a capital letter, how far
glyphs like l
and g
ascend or descend,
and so on. Using the default values for these metrics, for the fallback font, will typically result
in a layout shift, when the browser replaces the fallback with the actual webfont. Let’s see
how Fontaine can help!
🎁 Final Solution #
Fontaine has metrics for common webfonts, it sources them from the Capsize typography tooling. Using modern CSS, it can override the layout of the fallback font. This might make it look a little more compact or stretched out (depending on font relative sizes), than normal. However, this layout override results in zero, or very little layout shift when the browser swaps fonts during page load.
Using modern CSS, Fontaine adds overrides for the fallback fonts. We will see how to configure it in the next section. Below, is the code generated by Fontaine for the Overpass webfont with Arial and Roboto as fallbacks.
In line 3
, Fontaine has added Overpass fallback
to the --font-family
custom property (it was originally --font-family: "Overpass"
). As well as that, it has added new @font-face
directives for Roboto
and Arial (lines 13
– 28
).
⚙️ SvelteKit Fontaine: Configuration #
As it happens, Fontaine configuration is quite straightforward. We are assuming you self-host
fonts in your project and have already included the font-display: swap
directive in your CSS. Use the Google Webfonts Helper by Mario Ranftl to get the CSS snippets for your chosen webfonts , and also download the font WOFF2 files.
How to use Fontaine with SvelteKit to reduce Font Swap CLS #
-
Add the
fontaine
package to your SvelteKit project: -
Update your
vite.config.ts
file to use theFontaineTransforms
:I picked Arial as a fallback here, as I have a sans webfont. Roboto is a second fallback, worth including for Android devices. - Run your project as normal. Inspecting CSS source in dev mode, or for a built site running in preview mode, you should be able to find the CSS modifications outlined above.
🗳 Poll #
💯 SvelteKit Fontaine: Checking your Work #
You can check all is good by building your site and the running Lighthouse on it, locally, in preview mode. The difference will be most pronounced on mobile. For the basic layout above, I saw CLS drop from 3% to zero when I switched on Fontaine. Let me know what improvements you get.
🙌🏽 SvelteKit Fontaine: Wrapping Up #
In this post, we saw why you would want to use Fontaine in your SvelteKit project, as well as how to use it. More specifically, we saw:
- what problems Fontaine solves;
- how to use Fontaine with Vite to reduce CLS; and
- how to might check CLS is actually reduced.
Please see the full repo code on the Rodney Lab GitHub repo . I do hope you have found this post useful and can use the code in your own Svelte project. Let me know if you have any suggestions for improvements to the post. Drop a comment below or reach out on other channels.
🏁 SvelteKit Fontaine: Summary #
Does Fontaine work with SvelteKit? #
- Yes. Fontaine supports Vite, which is the tooling that SvelteKit uses under the hood. Just add fontaine as a project dependency, then add your fallbacks within the Vite config file (`vite.config.ts`).
What are safe font swap fallbacks? #
- Including the `font-display: swap` directive in your CSS when self-hosting fonts should improve user experience. The browser will display text using your fallback font, while waiting for a slow webfont download. You will want to choose fallbacks supported by most devices. The vast majority of desktop browsers will provide Times New Roman and Arial. This makes Times New Roman a safe fallback for serif fonts, and Arial a safe fallback for sans fonts. That said, typically Android devices do not provide either of those two fonts, though they do have Roboto. To cover more bases, include Roboto as a second fallback for both serif and sans-serif fonts.
How can you quickly add font-face CSS directives when self-hosting fonts? #
- The google-webfonts-helper by Mario Ranfl (https://gwfh.mranftl.com/fonts) is a convenient way to generate font-face CSS as well as download WOFF2 files for your chosen webfonts. By default, it generates CSS to support just modern WOFF2 files, though you can configure it to generate CSS supporting legacy browsers too.
🙏🏽 SvelteKit Fontaine: Feedback #
If you have found this post useful, see links below for further related content on this site. I do hope you learned one new thing from the video. Let me know if there are any ways I can improve on it. I hope you will use the code or starter in your own projects. Be sure to share your work on Twitter, giving me a mention, so I can see what you did. Finally, be sure to let me know ideas for other short videos you would like to see. Read on to find ways to get in touch, further below. If you have found this post useful, even though you can only afford even a tiny contribution, please consider supporting me through Buy me a Coffee.
Just dropped a new post on reducing font swap CLS in ❤️SvelteKit using Fontaine.
— Rodney (@askRodney) June 26, 2023
Hope you find it useful!
#learnsvelte #askRodneyhttps://t.co/kPtmKqwBPY
Finally, feel free to share the post on your social media accounts for all your followers who will find it useful. As well as leaving a comment below, you can get in touch via @askRodney on Twitter and also askRodney on Telegram . Also, see further ways to get in touch with Rodney Lab. I post regularly on SvelteKit as well as Search Engine Optimization among other topics. Also, subscribe to the newsletter to keep up-to-date with our latest projects.