Tag: fontdisplay

Google Fonts is Adding font-display

Google announced at I/O that their font service will now support the font-display property which resolves a number of web performance issues. If you’re hearing cries of joy, that’s probably Chris as he punches the air in celebration. He’s wanted this feature for some time and suggests that all @font-face blocks ought to consider using the property.

Zach Leatherman has the lowdown:

This is big news—it means developers now have more control over Google Fonts web font loading behavior. We can enforce instant rendering of fallback text (when using font-display: swap) rather than relying on the browser default behavior of invisible text for up to 3 seconds while the web font request is in-flight.

It’s also a bit of trailblazing, too. To my knowledge, this is the first web font host that’s shipping support for this very important font-display feature.

Yes, a big deal indeed! You may recall that font-display instructs the browser how (and kinda when) to load fonts. That makes it a possible weapon to fight fight FOUT and FOIT issues. Chris has mentioned how he likes the optional value for that exact reason.

@font-face {   font-family: "Open Sans Regular";   src: url("...");   font-display: optional; }

Oh and this is a good time to remind everyone of Monica Dinculescu’s font-display demo where she explores all the various font-display values and how they work in practice. It’s super nifty and worth checking out.

Direct Link to ArticlePermalink

The post Google Fonts is Adding font-display appeared first on CSS-Tricks.


, , ,

Google Fonts and font-display

The font-display descriptor in @font-face blocks is really great. It goes a long way, all by itself, for improving the perceived performance of web font loading. Loading web fonts is tricky stuff and having a tool like this that works as well as it does is a big deal for the web.

It’s such a big deal that Google’s own Pagespeed Insights / Lighthouse will ding you for not using it. A cruel irony, as their own Google Fonts (easily the most-used repository of custom fonts on the web) don’t offer any way to use font-display.

Summarized by Daniel Dudas here:

Google Developers suggests using Lighthouse -> Lighthouse warns about not using font-display on loading fonts -> Web page uses Google Fonts the way it’s suggested on Google Fonts -> Google Fonts doesn’t supports font-display -> Facepalm.

Essentially, we developers would love a way to get font-display in that @font-face block that Google serves up, like this:

@font-face {   font-family: "Open Sans Regular";   src: url("...");   font-display: swap; }

Or, some kind of alternative that is just as easy and just as effective.

Seems like query params is a possibility

When you use a Google Font, they give you a URL that coughs up a stylesheet and makes the font work. Like this:


They also support URL params for a variety of things, like weights:


And subsets:

http://fonts.googleapis.com/css?family=Creepster&text=TRICKS https://fonts.googleapis.com/css?family=Open+Sans:400,700&subset=cyrillic

So, why not…


The lead on the project says that caching is an issue with that (although it’s been refuted by some since they already support arbitrary text params).

Adding query params reduces x-site cache hits. If we end up with something for font-display plus a bunch of params for variable fonts that could present us with problems.

They say that again later in the thread, so it sounds unlikely that we’re going to get query params any time soon, but I’d love to be wrong.

Option: Download & Self-Host Them

All Google Fonts are open source, so we can snag a copy of them to use for whatever we want.

Once the font files are self-hosted and served, we’re essentially writing @font-face blocks to link them up ourselves and we’re free to include whatever font-display we want.

Option: Fetch & Alter

Robin Richtsfeld posted an idea to run an Ajax call from JavaScript for the font, then alter the response to include font-display and inject it.

const loadFont = (url) => {   // the 'fetch' equivalent has caching issues   var xhr = new XMLHttpRequest();   xhr.open('GET', url, true);   xhr.onreadystatechange = () => {     if (xhr.readyState == 4 && xhr.status == 200) {       let css = xhr.responseText;       css = css.replace(/}/g, 'font-display: swap; }');        const head = document.getElementsByTagName('head')[0];       const style = document.createElement('style');       style.appendChild(document.createTextNode(css));       head.appendChild(style);     }   };   xhr.send(); }  loadFont('https://fonts.googleapis.com/css?family=Rammetto+One');

Clever! Although, I’m not entirely sure how this fits into the world of font loading. Since we’re now handling loading this font in JavaScript, the loading performance is tied to when and how we’re loading the script that runs this. If we’re going to do that, maybe we ought to look into using the official webfontloader?

Option: Service Workers

Similar to above, we can fetch the font and alter it, but do it at the Service Worker level so we can cache it (perhaps more efficiently). Adam Lane wrote this:

self.addEventListener("fetch", event => {   event.respondWith(handleRequest(event)) });  async function handleRequest(event) {   const response = await fetch(event.request);   if (event.request.url.indexOf("https://fonts.googleapis.com/css") === 0 && response.status < 400) {     // Assuming you have a specific cache name setup        const cache = await caches.open("google-fonts-stylesheets");     const cacheResponse = await cache.match(event.request);     if (cacheResponse) {       return cacheResponse;   }   const css = await response.text();   const patched = css.replace(/}/g, "font-display: swap; }");   const newResponse = new Response(patched, {headers: response.headers});   cache.put(event.request, newResponse.clone());     return newResponse;   }   return response; }

Even Google agrees that using Service Workers to help Google Fonts is a good idea. Workbox, their library for abstracting service worker management, uses Google Fonts as the first demo on the homepage:

// Cache the Google Fonts stylesheets with a stale while revalidate strategy. workbox.routing.registerRoute(   /^https://fonts.googleapis.com/,   workbox.strategies.staleWhileRevalidate({     cacheName: 'google-fonts-stylesheets',   }), );  // Cache the Google Fonts webfont files with a cache first strategy for 1 year. workbox.routing.registerRoute(   /^https://fonts.gstatic.com/,   workbox.strategies.cacheFirst({     cacheName: 'google-fonts-webfonts',     plugins: [       new workbox.cacheableResponse.Plugin({         statuses: [0, 200],       }),       new workbox.expiration.Plugin({         maxAgeSeconds: 60 * 60 * 24 * 365,       }),     ],   }), );

Option: Cloudflare Workers

Pier-Luc Gendreau looked into using Cloudflare workers to handle this, but then followed up with Supercharge Google Fonts with Cloudflare and Service Workers, apparently for even better perf.

It has a repo.

Option: Wait for @font-feature-values

One of the reasons Google might be dragging its heels on this (they’ve said the same), is that there is a new CSS @rule called @font-feature-values that is designed just for this situation. Here’s the spec:

This mechanism can be used to set a default display policy for an entire font-family, and enables developers to set a display policy for @font-face rules that are not directly under their control. For example, when a font is served by a third-party font foundry, the developer does not control the @font-face rules but is still able to set a default font-display policy for the provided font-family. The ability to set a default policy for an entire font-family is also useful to avoid the ransom note effect (i.e. mismatched font faces) because the display policy is then applied to the entire font family.

There doesn’t seem to be much movement at all on this (just a little), but it doesn’t seem pretty awesome to wait on it.

The post Google Fonts and font-display appeared first on CSS-Tricks.


, ,