{"id":279900,"date":"2018-12-19T07:26:12","date_gmt":"2018-12-19T14:26:12","guid":{"rendered":"http:\/\/css-tricks.com\/?p=279900"},"modified":"2021-04-12T12:09:16","modified_gmt":"2021-04-12T19:09:16","slug":"google-fonts-and-font-display","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/google-fonts-and-font-display\/","title":{"rendered":"Google Fonts and font-display"},"content":{"rendered":"\n

Hey! This whole article is about a time before May 2019 in which Google Fonts didn’t offer a way to use font-display without self-hosting the fonts.<\/strong><\/p>\n\n\n\n

To use font-display with Google Fonts, you include a URL parameter like &display=swap<\/code> in the URL, like https:\/\/fonts.googleapis.com\/css?family=Open+Sans&display=swap. If you’re copying code from Google Fonts now, it’s the default, so you get it automatically, but you might want to add it if you have existing URLs to Google fonts lingering around, or you want to change it to something like optional<\/code><\/a> if you prefer that.<\/p>\n\n\n\n

Zach Leatherman notes there are still some things to wish for<\/a>, like stable URL’s for the fonts so we could link up the fonts in our own CSS, preventing the double-hop needed right now.<\/p>\n\n\n\n


\n\n\n\n

This is the original article:<\/strong><\/p>\n\n\n\n

The font-display<\/code><\/a> descriptor in @font-face<\/a><\/code> 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.<\/p>\n\n\n\n

It’s such a big deal that Google’s own Pagespeed Insights \/ Lighthouse<\/a> 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<\/code>.<\/p>\n\n\n\n

Summarized by Daniel Dudas here:<\/p>\n\n\n\n

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

Essentially, we developers would love a way to get font-display<\/code> in that @font-face<\/code> block that Google serves up, like this:<\/p>\n\n\n\n

@font-face {\n  font-family: \"Open Sans Regular\";\n  src: url(\"...\");\n  font-display: swap;\n}<\/code><\/pre>\n\n\n\n

Or, some kind of alternative that is just as easy and just as effective.<\/p>\n\n\n

Seems like query params is a possibility<\/h3>\n\n\n

When you use a Google Font, they give you a URL that coughs up a stylesheet and makes the font work. Like this:<\/p>\n\n\n\n

https:\/\/fonts.googleapis.com\/css?family=Roboto<\/code><\/pre>\n\n\n\n

They also support URL params for a variety of things, like weights:<\/p>\n\n\n\n

https:\/\/fonts.googleapis.com\/css?family=Open+Sans:400,700<\/code><\/pre>\n\n\n\n

And subsets:<\/p>\n\n\n\n

http:\/\/fonts.googleapis.com\/css?family=Creepster&text=TRICKS\nhttps:\/\/fonts.googleapis.com\/css?family=Open+Sans:400,700&subset=cyrillic<\/code><\/pre>\n\n\n\n

So, why not…<\/p>\n\n\n\n

http:\/\/fonts.googleapis.com\/css?family=Creepster&display=swap<\/code><\/pre>\n\n\n\n

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

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.<\/p><\/blockquote>\n\n\n\n

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.<\/p>\n\n\n

Option: Download & Self-Host Them<\/h3>\n\n\n

All Google Fonts are open source, so we can snag a copy of them to use for whatever we want.<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

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

Option: Fetch & Alter<\/h3>\n\n\n

Robin Richtsfeld posted an idea to run an Ajax call from JavaScript for the font, then alter the response to include font-display<\/code> and inject it.<\/p>\n\n\n\n

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

Clever!<\/a> 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<\/a>?<\/p>\n\n\n

Option: Service Workers<\/h3>\n\n\n

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:<\/p>\n\n\n\n

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

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

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

Option: Cloudflare Workers<\/h3>\n\n\n

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

It has a repo.<\/a><\/p>\n\n\n

Option: Wait for @font-feature-values<\/code><\/h3>\n\n\n

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<\/code> called @font-feature-values<\/code> that is designed just for this situation<\/em>. Here’s the spec:<\/a><\/p>\n\n\n\n

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.<\/p><\/blockquote>\n\n\n\n

There doesn’t seem to be much movement at all on this<\/a> (just a little<\/a>), but it doesn’t seem pretty awesome to wait on it.<\/p>\n","protected":false},"excerpt":{"rendered":"

Hey! This whole article is about a time before May 2019 in which Google Fonts didn’t offer a way to use font-display without self-hosting the fonts. To use font-display with Google Fonts, you include a URL parameter like &display=swap in the URL, like https:\/\/fonts.googleapis.com\/css?family=Open+Sans&display=swap. If you’re copying code from Google Fonts now, it’s the default, […]<\/p>\n","protected":false},"author":3,"featured_media":272639,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"sig_custom_text":"","sig_image_type":"featured-image","sig_custom_image":0,"sig_is_disabled":false,"inline_featured_image":false,"c2c_always_allow_admin_comments":false,"footnotes":"","jetpack_publicize_message":"Google Developers\/Lighthouse advocate using font-display but Google Fonts doesn't support it. Here are a few options for how to handle that.","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":[]},"categories":[4],"tags":[1547,817,1548],"jetpack_publicize_connections":[],"acf":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/06\/google-fonts.png?fit=1200%2C600&ssl=1","jetpack-related-posts":[{"id":311329,"url":"https:\/\/css-tricks.com\/the-fastest-google-fonts\/","url_meta":{"origin":279900,"position":0},"title":"The Fastest Google Fonts","date":"May 22, 2020","format":false,"excerpt":"When you use font-display: swap;, which Google Fonts does when you use the default &display=swap part of the URL , you're already saying, \"I'm cool with FOUT,\" which is another way of saying web text is displayed right away, and when the web font is ready, \"swap\" to it. There\u2026","rel":"","context":"In "Link"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/06\/google-fonts.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":334948,"url":"https:\/\/css-tricks.com\/the-best-font-loading-strategies-and-how-to-execute-them\/","url_meta":{"origin":279900,"position":1},"title":"The Best Font Loading Strategies and How to Execute Them","date":"March 2, 2021","format":false,"excerpt":"Zach Leatherman wrote up a comprehensive list of font loading strategies that have been widely shared in the web development field. I took a look at this list before, but got so scared (and confused), that I decided not to do anything at all. I don't know how to begin\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/12\/performance-waterfall-fonts.jpg?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":304786,"url":"https:\/\/css-tricks.com\/google-fonts-variable-fonts\/","url_meta":{"origin":279900,"position":2},"title":"Google Fonts + Variable Fonts","date":"March 7, 2020","format":false,"excerpt":"I see Google Fonts rolled out a new design (Tweet). Compared to the last big redesign, this feels much more iterative. I can barely tell the difference really, except it's blue instead of red and this one pretty rad checkbox: Show only variable fonts. An option to only show variable\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/03\/google-fonts-redesign.png?fit=1200%2C745&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":317559,"url":"https:\/\/css-tricks.com\/getting-the-most-out-of-variable-fonts-on-google-fonts\/","url_meta":{"origin":279900,"position":3},"title":"Getting the Most Out of Variable Fonts on Google Fonts","date":"July 30, 2020","format":false,"excerpt":"I have spent the past several years working (alongside a bunch of super talented people) on a font family called Recursive Sans & Mono, and it just launched officially on Google Fonts! Wanna try it out super fast? Here\u2019s the embed code to use the full Recursive variable font family\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/07\/recursive-specimen.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":306566,"url":"https:\/\/css-tricks.com\/dark-mode-and-variable-fonts\/","url_meta":{"origin":279900,"position":4},"title":"Dark mode and variable fonts","date":"April 23, 2020","format":false,"excerpt":"Not so long ago, we wrote about dark mode in CSS and I\u2019ve been thinking about how white text on a black background is pretty much always harder to read than black text on a white background. After thinking about this for a while, I realized that we can fix\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/04\/dark-light-text-backgrounds.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":301816,"url":"https:\/\/css-tricks.com\/how-we-tagged-google-fonts-and-created-goofonts-com\/","url_meta":{"origin":279900,"position":5},"title":"How We Tagged Google Fonts and Created goofonts.com","date":"January 15, 2020","format":false,"excerpt":"GooFonts\u00a0is a side project signed by a developer-wife and a designer-husband, both of them big fans of typography. We\u2019ve been tagging\u00a0Google Fonts\u00a0and built a website that makes searching through and finding the right font easier. GooFonts\u00a0uses WordPress in the back\u00a0end and\u00a0NuxtJS\u00a0(a\u00a0Vue.js framework)\u00a0on the front\u00a0end. I\u2019d love to tell you the\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/279900"}],"collection":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/comments?post=279900"}],"version-history":[{"count":9,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/279900\/revisions"}],"predecessor-version":[{"id":338203,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/279900\/revisions\/338203"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/media\/272639"}],"wp:attachment":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/media?parent=279900"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/categories?post=279900"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/tags?post=279900"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}