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.
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.
The advice offered on the Chrome Developers site, to ensure the font remains visible, is to use the
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.
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
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
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!
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.
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
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.
fontainepackage to your SvelteKit project:
vite.config.tsfile to use the
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.
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.
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.
- 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`).
- 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.
- 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.
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.
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.