Opens an external site in a new window
Mental Health Awareness Month
“Community”
RODNEY LAB
  • Home
  • Plus +
  • Newsletter
  • Links
  • Profile
RODNEY LAB
  • Home
  • Plus +
  • Newsletter
  • Links

SvelteKit Fontaine: Reduce Custom Font CLS ✍🏽 # SvelteKit Fontaine: Reduce Custom Font CLS ✍🏽 #

blurry low resolution placeholder image Svelte Real-time Multiplayer Game
  1. Home Rodney Lab Home
  2. Blog Posts Rodney Lab Blog Posts
  3. SvelteKit SvelteKit Blog Posts
<PREVIOUS POST
NEXT POST >
LATEST POST >>

SvelteKit Fontaine: Reduce Custom Font CLS ✍🏽 #

Published: 2 years ago
5 minute read
Gunning Fog Index: 6
Content by Rodney
blurry low resolution placeholder image Author Image: Rodney from Rodney Lab
SHARE:

🏄🏽 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 #

blurry low resolution placeholder image SvelteKit Fontaine: text rendered in the fallback Arial font with the words compiled, compact and complete able to fit on just two lines.
SvelteKit Fontaine: Fallback Font
blurry low resolution placeholder image SvelteKit Fontaine: text rendered in the webfont font with the words compiled, compact and complete needing to be spread over three lines.
SvelteKit Fontaine: Webfont

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.

.svelte-kit/output/client/_app/immutable/assets/abc123.css
css
    
1 :root {
2 /* TRUNCATED... */
3 --font-family: "Overpass", "Overpass fallback";
4 /* TRUNCATED... */
5 }
6 @font-face {
7 font-display: swap;
8 font-family: Overpass;
9 font-style: normal;
10 font-weight: 400;
11 src: url(../../../fonts/overpass-v12-latin-regular.woff2) format("woff2");
12 }
13 @font-face {
14 font-family: Overpass fallback;
15 src: local("Roboto");
16 size-adjust: 100.5896%;
17 ascent-override: 87.7824%;
18 descent-override: 38.0755%;
19 line-gap-override: 0%;
20 }
21 @font-face {
22 font-family: Overpass fallback;
23 src: local("Arial");
24 size-adjust: 100.7009%;
25 ascent-override: 87.6854%;
26 descent-override: 38.0334%;
27 line-gap-override: 0%;
28 }
29 /* TRUNCATED... */

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 #

  1. Add the fontaine package to your SvelteKit project:
        
    pnpm add -D fontaine
  2. Update your vite.config.ts file to use the FontaineTransforms:
    vite.config.ts
    typescript
        
    1 import { sveltekit } from "@sveltejs/kit/vite";
    2 import { FontaineTransform } from "fontaine";
    3 import { defineConfig } from "vite";
    4
    5 export default defineConfig({
    6 plugins: [
    7 sveltekit(),
    8 FontaineTransform.vite({ fallbacks: ["Arial", "Roboto"] }),
    9 ],
    10 });
    I picked Arial as a fallback here, as I have a sans webfont. Roboto is a second fallback, worth including for Android devices.
  3. 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 #

How do you self-host fonts in your SvelteKit projects?
Voting reveals latest results.

💯 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.

blurry low resolution placeholder image ask Rodney X (formerly Twitter) avatar

Rodney

@askRodney

Just dropped a new post on reducing font swap CLS in ❤️SvelteKit using Fontaine.

Hope you find it useful!

#learnsvelte #askRodneyhttps://t.co/kPtmKqwBPY

— Rodney (@askRodney) June 26, 2023

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.

Thanks for reading this post. I hope you found it valuable. Please get in touch with your feedback and suggestions for posts you would like to see. Read more about me …

blurry low resolution placeholder image Rodney from Rodney Lab
TAGS:
SVELTEKITCSS

Related Posts

blurry low resolution placeholder image Astro Font Fallbacks with Capsize: reduce CLS 📏

Astro Font Fallbacks with Capsize: reduce CLS 📏

astro
css
<PREVIOUS POST
NEXT POST >
LATEST POST >>

Leave a comment …

Your information will be handled in line with our Privacy Policy .

Ask for more

1 Nov 2022 — Astro Server-Side Rendering: Edge Search Site
3 Oct 2022 — Svelte eCommerce Site: SvelteKit Snipcart Storefront
1 Sept 2022 — Get Started with SvelteKit Headless WordPress

Copyright © 2020 – 2025 Rodney Johnson. All Rights Reserved. Please read important copyright and intellectual property information.

  • Home
  • Profile
  • Plus +
  • Newsletter
  • Contact
  • Links
  • Terms of Use
  • Privacy Policy
We use cookies  to enhance visitors’ experience. Please click the “Options” button to make your choice.  Learn more here.