Tag: Fonts

The Fastest Google Fonts

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 is already an async nature to what you are doing, so you might as well extend that async-ness to the rest of the font loading. Harry Roberts:

If you’re going to use font-display for your Google Fonts then it makes sense to asynchronously load the whole request chain.

Harry’s recommended snippet:

<link rel="preconnect"       href="https://fonts.gstatic.com"       crossorigin />  <link rel="preload"       as="style"       href="$  CSS&display=swap" />  <link rel="stylesheet"       href="$  CSS&display=swap"       media="print" onload="this.media='all'" />

$ CSS is the main part of the URL that Google Fonts gives you.

Looks like a ~20% render time savings with no change in how it looks/feels when loading/. Other than that, it’s faster.

Direct Link to ArticlePermalink

The post The Fastest Google Fonts appeared first on CSS-Tricks.

CSS-Tricks

, ,

Chrome + System Fonts Snafu

There was just a bug late last year where system fonts (at least on Mac, I don’t know what the story was on other platforms) in Chrome appeared too thin and tracked-in at small sizes and too thick and tracked-out at larger sizes. That one was fixed, thankfully. But while it was a problem, it was the reason I gave up on system fonts for now and switched something else. A performance loss but aesthetic gain.

Now there is a new much worse bug, where the system font can’t be bolded. It’s not great, as a ton of sites roll with the system font stack as it has two major benefits: 1) it can help your site look like the operating system 2) it has great performance as the site doesn’t need to download/display and custom fonts.

Jon Henshaw wrote it up:

… the bug caught the attention of Adam Argyle, maker of VisBug and Chrome CSS Developer Advocate at Google. Argyle created a Chromium bug report, but the Chromium development team ultimately decided it wasn’t a blocker for releasing version 81. That resulted in sites like Coywolf not being able to use bold text for fonts that are larger than 16px (e.g., every heading).

The bug won’t be fixed in version 82 because the Chromium team announced that they’re skipping it, and will be releasing version 83 in mid-May instead. Argyle assured everyone on the original GitHub bug report that it would be fixed in version 83.

Above is Jon’s site. Andy Bell’s site got hit by it too.

So we’re looking at 4 weeks or so. Adam proposed a temporary fix of going Helvetica for now:

body {   font-family: -apple-system, Helvetica; }

I guess with -apple-system in there, older versions of Chrome/macOS still might be able to benefit from system fonts? Not sure.

That brings up a source of confusion for me. When I first heard of using system font stacks, there was -apple-system and BlinkMacSystemFont and you were supposed to use them in that order in the font stack. Then came along -system-ui, and that seemed to work well all by itself and that was nice as it was obviously less Mac-specific. But there is also system-ui (no starting dash), and that seems to do the same thing and I’m not sure which is correct. Now it looks like the plan is ui-sans-serif and friends (like ui-serif and ui-monospace). I like the idea, but I’d love to hear clarity from browser vendors on what the recommended use is. Are we in a spot like this?

/* Just a guess... */ body {   font-family:      ui-sans-serif,      system-ui,      -system-ui,      -apple-system,     BlinkMacSystemFont,     Roboto, Helvetica, Arial,      sans-serif,      "Apple Color Emoji"; }

Another observation from me… as I was trying to replicate this on Chrome 81, at first I was like “weird, works for me”, because I was trying out the bolding on default 16px text. I noticed that it was when the font was 20px or bigger the problem kicked in:

Bramus has an alternative fix idea: use Inter.

The post Chrome + System Fonts Snafu appeared first on CSS-Tricks.

CSS-Tricks

, , ,
[Top]

Dark mode and variable fonts

Not so long ago, we wrote about dark mode in CSS and I’ve 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 that problem by making the text thinner in dark mode using variable fonts!

Here’s an example of the problem where I’m using the typeface Yanone Kaffeesatz from Google Fonts. Notice that the section with white text on a black background looks heavier than the section with black text on a white background.

Oddly enough, these two bits of text are actually using the same font-weight value of 400. But to my eye, the white text looks extra bold on a black background.

Stare at this example for a while. This is just how white text looks on a darker background; it’s how our eyes perceive shapes and color. And this might not be a big issue in some cases but reading light text on a dark background is always way more difficult for readers. And if we don’t take care designing text in a dark mode context, then it can feel as if the text is vibrating as we read it.

How do we fix this?

Well, this is where variable fonts come in! We can use a lighter font weight to make the text easier to read whenever dark mode is active:

body {   font-weight: 400; }  @media (prefers-color-scheme: dark) {   body {     font-weight: 350;   } }

Here’s how that looks with this new example:

This is better! The two variants now look a lot more balanced to me.

Again, it’s only a small difference, but all great designs consist of micro adjustments like this. And I reckon that, if you’re already using variable fonts and loading all these weights, then you should definitely adjust the text so it’s easier to read.

This effect is definitely easier to spot if we compare the differences between longer paragraphs of text. Here we go, this time in Literata:

Notice that the text on the right feels bolder, but it just isn’t. It’s simply an optical allusion — both examples above have a font-weight of 500.

So to fix this issue we can do the same as the example above:

body {   font-weight: 500; }  @media (prefers-color-scheme: dark) {   body {     font-weight: 400;   } }

Again, it’s a slight change but it’s important because at these sizes every typographic improvement we make helps the reading experience.

Oh and here’s a quick Google fonts tip!

Google Fonts lets you can add a font to your website by adding a <link> in the <head> of the document, like this:

<head>   <link href="https://fonts.googleapis.com/css2?family=Rosario:wght@515&display=swap" rel="stylesheet">  </head>

That’s using the Rosario typeface and adding a font-weight of 515 — that’s the bit in the code above that says wght@515. Even if this happens to be a variable font, 515 only this font weight that’s downloaded. If we try to do something like this:

body {   font-weight: 400; }

…nothing will happen! In fact, the font won’t load at all. Instead, we need to declare which range of font-weight values we want by doing the following:

<link href="https://fonts.googleapis.com/css2?family=Yanone+Kaffeesatz:wght@300..500&display=swap" rel="stylesheet">

This @300..500 bit in the code above is what tells Google Fonts to download a font file with all the weights between 300 and 500. Alternatively, adding a ; between each weight will then only download weights 300 and 500 – so, for example, you can’t pick weight 301:

<link href="https://fonts.googleapis.com/css2?family=Yanone+Kaffeesatz:wght@300;500&display=swap" rel="stylesheet">

It took me a few minutes to figure out what was going wrong and why the font wasn’t loading at all, so hopefully the Google Fonts team can make that a bit clearer with the embed codes in the future. Perhaps there should be an option or a toggle somewhere to select a range or specific weights (or maybe I just didn’t see it).

Either way, I think all this is why variable fonts can be so gosh darn helpful; they allow us to adjust text in ways that we’ve never been able to do before. So, yay for variable fonts!

The post Dark mode and variable fonts appeared first on CSS-Tricks.

CSS-Tricks

, , ,
[Top]

Considerations When Choosing Fonts for a Multilingual Website

As a front-end developer working for clients all over the world, I’ve always struggled to deal with multilingual websites — especially cases where both right-to-left (RTL) and left-to-right (LTR) are used. That said, I’ve learned a few things along the way and am going to share a few tips in this post.

Let’s work in Arabic and English, not just because Arabic is my native language, but because it’s a classic example of RTL in use.

Adding RTL support to a site

Before this though, we’ll want to add support for an RTL language on our site. There are two ways we can go about this, both of which aren’t exactly ideal.

Not ideal: Use a specific font for each direction

The first way we could go about this is to rely on the direction (dir) attribute on any given element (which is usually the <html> element so it sets the direction globally):

/* For LTR, use Roboto */ [dir=ltr] body {   font-family: "Roboto", sans-serif; }  /* For RTL, use Amiri */ [dir=rtl] body {   font-family: "Amiri", sans-serif; }

PostCSS-RTL makes it even easier to generate styles for each direction, but the issue with this method is that you are only using one font which is not ideal if you have multiple languages in one paragraph.

Here’s why. You’ll find that multi-lingual paragraphs mess up the UI because the Arabic glyphs are given a default font that doesn’t align with the element.

It might be worse in some browsers over others.

Also not ideal: Use one single font that supports both languages

The second option could be using fonts that offer support for both directions. However, in my personal experience, using just one font for both languages limits creativity and freedom to use a different font for each direction. It might not be that bad, depending on the design requirements. But I’ve definitely worked on projects where it makes a difference.

OK, so what then?

We need a simpler solution. According to MDN:

Font selection does not simply stop at the first font in the list that is on the user’s system. Rather, font selection is done one character at a time, so that if an available font does not have a glyph for a needed character, the latter fonts are tried.

Meaning, we can still use the font-family property but using a fallback in cases where the first font doesn’t have a glyph for a character. This actually solves both of the issues above, two birds with one stone style!

body {   font-family: 'Roboto', 'Amiri', 'Galada', sans-serif; }

Why does this work?

Just like the way flexbox and CSS grid, make CSS layouts a lot more flexible, the font matching algorithm makes it even easier to work with content in different languages. Here’s what W3C says about it matching characters to fonts:

When text contains characters such as combining marks, ideally the base character should be rendered using the same font as the mark, this assures proper placement of the mark. For this reason, the font matching algorithm for clusters is more specialized than the general case of matching a single character by itself. For sequences containing variation selectors, which indicate the precise glyph to be used for a given character, user agents always attempt system font fallback to find the appropriate glyph before using the default glyph of the base character.

(Emphasis mine)

And how are fonts matched? The spec outlines the steps the algorithm takes, which I’ll paraphrase here.

  • The browser looks at a cluster of text and tries to match it to the list of fonts that are declared in CSS.
  • If it finds a font that supports all of the characters, great! That’s what gets used.
  • If the browser doesn’t find a font that supports all of the characters, it re-reads the list of fonts to find one that supports the unmatched characters and applies it to those specific characters. 
  • If the browser doesn’t find a font in the list that matches neither all of the characters in the cluster nor individual ones, then it reaches for the default system font and checks that it supports all of the characters.
  • If the default system font matches, again, great! That’s what gets used.
  • If the system font doesn’t work, that’s where the browser renders a broken glyph.

Let’s talk performance

The sequence we just looked at could be taxing on a site’s performance. Imagine the browser having to loop through every defined fallback, match specific characters to glyphs, and download font files based on what it finds. That can add up to a lot of work, not to mention FOUT and other rendering weirdness.

The goal is to let the font matching algorithm decide which font to apply to each text instead of relying on one font for both languages or adding extra CSS to handle different directions. If a font is never applied to anything (say a particular page is in RTL and happens to not have any LTR text on it, or vice versa) the font further down the stack that isn’t used is never downloaded.

Making that happen requires selecting good multilingual fonts. Good multilingual fonts are ones that have glyphs for as many characters you anticipate using on a page. And if you are unable to find one that supports them all, using one that supports most of them and then falling back to another font that does is an efficient way to go. If that happens to be the default system font, that’s just as great because it’s one less downloaded font file.


The good thing about letting the font-family property decide the font for each glyph (instead of making extra CSS selectors for each direction) is that the behavior is already there as we outlined earlier — we simply need to make use of it. 

The post Considerations When Choosing Fonts for a Multilingual Website appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

Google Fonts + Variable Fonts

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 fonts is a pretty bold feature for the main navigation up there. That’s a strong commitment to this feature. With Google Fonts having about 90% of the market share of hosted web fonts and serving trillions of requests, that’s going to spike interest and usage of variable fonts in a big way. Web designers and developers have been excited about variable fonts for a while, but I’d bet this is the year we start seeing it in the wild in a much bigger way.

Something about variable fonts inspired the micro-site. See v-fonts.com and Axis-Praxis. Here’s come another one: variablefonts.io! Like the others, it also has interactive examples, but it’s also full of direct up-to-date advice and links to resources.

Another thing that’s really great that Google Fonts has done somewhat recently is allowed for the usage of font-display. It’s got a good default (swap), and is easily changable as a query param. Matt Hobbs has a recent article about what it is, how important it can be, and how to use it.

And while we’re talking Google Fonts, I ran across the browser extension Snapfont the other day. It’s a pay-what-you-want thing (I tossed them a fiver).

It just hard-replaces every font on the site with one you pick to get a quick taste of it. There are no options, so it’s not for fine-tuning any choices. The “Heading” button didn’t even work for me. But I like how simple and easy it was to get a taste for a site with a new font.

The post Google Fonts + Variable Fonts appeared first on CSS-Tricks.

CSS-Tricks

, ,
[Top]

How We Tagged Google Fonts and Created goofonts.com

GooFonts is a side project signed by a developer-wife and a designer-husband, both of them big fans of typography. We’ve been tagging Google Fonts and built a website that makes searching through and finding the right font easier.

GooFonts uses WordPress in the back end and NuxtJS (a Vue.js framework) on the front end. I’d love to tell you the story behind goofonts.com and share a few technical details regarding the technologies we’ve chosen and how we adapted and used them for this project.

Why we built GooFonts

At the moment of writing this article, there are 977 typefaces offered by Google Fonts. You can check the exact number at any moment using the Google Fonts Developer API. You can retrieve the dynamic list of all fonts, including a list of the available styles and scripts for each family.

The Google Fonts website provides a beautiful interface where you can preview all fonts, sorting them by trending, popularity, date, or name. 

But what about the search functionality? 

You can include and exclude fonts by five categories: serif, sans-serif, display, handwriting, and monospace.

You can search within scripts (like Latin Extended, Cyrillic, or Devanagari (they are called subsets in Google Fonts). But you cannot search within multiple subsets at once.

You can search by four properties: thickness, slant, width, and “number of styles.” A style, also called variant, refers both to the style (italic or regular) and weights (100, 200, up to 900). Often, the body font requires three variants: regular, bold, and italic. The “number of styles” property sorts out fonts with many variants, but it does not allow to select fonts that come in the “regular, bold, italic” combo.

There is also a custom search field where you can type your query. Unfortunately, the search is performed exclusively over the names of the fonts. Thus, the results often include font families uniquely from services other than Google Fonts. 

Let’s take the “cartoon” query as an example. It results in “Cartoon Script” from an external foundry Linotype.

I can remember working on a project that demanded two highly stylized typefaces — one evoking the old Wild West, the other mimicking a screenplay. That was the moment when I decided to tag Google Fonts. 🙂

GooFonts in action

Let me show you how GooFonts works. The dark sidebar on the right is your  “search” area. You can type your keywords in the search field — this will perform an “AND” search. For example, you can look for fonts that are at once cartoon and slab. 

We handpicked a bunch of keywords — click any of them! If your project requires some specific subsets, check them in the subsets sections.  You can also check all the variants that you need for your font.

If you like a font, click its heart icon, and it will be stored in your browser’s localStorage. You can find your bookmarked fonts on the goofonts.com/bookmarks page. Together with the code, you might need to embed them.

How we built it: the WordPress part

To start, we needed some kind of interface where we could preview and tag each font. We also needed a database to store those tags. 

I had some experience with WordPress. Moreover, WordPress comes with its REST API,  which opens multiple possibilities for dealing with the data on the front end. That choice was made quickly.

I went for the most straightforward possible initial setup. Each font is a post, and we use post tags for keywords. A custom post type could have worked as well, but since we are using WordPress only for the data, the default content type works perfectly well.

Clearly, we needed to add all the fonts programmatically. We also needed to be able to programmatically update the fonts, including adding new ones or adding new available variants and subsets.

The approach described below can be useful with any other data available via an external API. In a custom WordPress plugin, we register a menu page from which we can check for updates from the API. For simplicity, the page will display a title, a button to activate the update and a progress bar for some visual feedback.

/**  * Register a custom menu page.   */ function register_custom_menu_page() {   add_menu_page(      'Google Fonts to WordPress',      'WP GooFonts',      'manage_options',      'wp-goofonts-menu',    function() { ?>             <h1>Google Fonts API</h1>     <button type="button" id="wp-goofonts-button">Run</button>     <p id="info"></p>             <progress id="progress" max="100" value="0"></progress>   <?php }   ); } add_action( 'admin_menu', 'register_custom_menu_page' );

Let’s start by writing the JavaScript part. While most of the examples of using Ajax with WordPress implements jQuery and the jQuery.ajax method, the same can be obtained without jQuery, using axios and a small helper Qs.js for data serialization.

We want to load our custom script in the footer, after loading axios and qs:

add_action( 'admin_enqueue_scripts' function() {   wp__script( 'axios', 'https://unpkg.com/axios/dist/axios.min.js' );   wp_enqueue_script( 'qs', 'https://unpkg.com/qs/dist/qs.js' );   wp_enqueue_script( 'wp-goofonts-admin-script', plugin_dir_url( __FILE__ ) . 'js/wp-goofonts.js', array( 'axios', 'qs' ), '1.0.0', true ); });

Let’s look how the JavaScript could look like:

const BUTTON = document.getElementById('wp-goofonts-button') const INFO = document.getElementById('info') const PROGRESS = document.getElementById('progress') const updater = {   totalCount: 0,   totalChecked: 0,   updated: [],   init: async function() {     try {       const allFonts = await axios.get('https://www.googleapis.com/webfonts/v1/webfonts?key=API_KEY&sort=date')       this.totalCount = allFonts.data.items.length       INFO.textContent = `Fetched $ {this.totalCount} fonts.`       this.updatePost(allFonts.data.items, 0)     } catch (e) {       console.error(e)     }   },   updatePost: async function(els, index) {     if (index === this.totalCount) {       return     }                     const data = {       action: 'goofonts_update_post',       font: els[index],     }     try {        const apiRequest = await axios.post(ajaxurl, Qs.stringify(data))        this.totalChecked++        PROGRESS.setAttribute('value', Math.round(100*this.totalChecked/this.totalCount))        this.updatePost(els, index+1)     } catch (e) {        console.error(e)       }    } }  BUTTON.addEventListener('click', () => {   updater.init() })

The init method makes a request to the Google Fonts API. Once the data from the API is available, we call the recursive asynchronous updatePost method that sends an individual font in the POST request to the WordPress server.

Now, it’s important to remember that WordPress implements Ajax in its specific way. First of all, each request must be sent to wp-admin/admin-ajax.php. This URL is available in the administration area as a global JavaScript variable ajaxurl.

Second, all WordPress Ajax requests must include an action argument in the data. The value of the action determines which hook tag will be used on the server-side.

In our case, the action value is goofonts_update_post. That means what happens on the server-side is determined by the wp_ajax_goofonts_update_post hook.

add_action( 'wp_ajax_goofonts_update_post', function() {   if ( isset( $ _POST['font'] ) ) {     /* the post tile is the name of the font */     $ title = wp_strip_all_tags( $ _POST['font']['family'] );     $ variants = $ _POST['font']['variants'];     $ subsets = $ _POST['font']['subsets'];     $ category = $ _POST['font']['category'];     /* check if the post already exists */     $ object = get_page_by_title( $ title, 'OBJECT', 'post' );     if ( NULL === $ object ) {       /* create a new post and set category, variants and subsets as tags */       goofonts_new_post( $ title, $ category, $ variants, $ subsets );     } else {       /* check if $ variants or $ subsets changed */       goofonts_update_post( $ object, $ variants, $ subsets );     }   } });  function goofonts_new_post( $ title, $ category, $ variants, $ subsets ) {   $ post_id =  wp_insert_post( array(     'post_author'  =>  1,     'post_name'    =>  sanitize_title( $ title ),     'post_title'   =>  $ title,     'post_type'    =>  'post',     'post_status'  => 'draft',     )   );   if ( $ post_id > 0 ) {     /* the easy part of tagging ;) append the font category, variants and subsets (these three come from the Google Fonts API) as tags */     wp_set_object_terms( $ post_id, $ category, 'post_tag', true );     wp_set_object_terms( $ post_id, $ variants, 'post_tag', true );     wp_set_object_terms( $ post_id, $ subsets, 'post_tag', true );   } }

This way, in less than a minute, we end up with almost one thousand post drafts in the dashboard — all of them with a few tags already in place. And that’s the moment when the crucial, most time-consuming part of the project begins. We need to start manually add tags for each font one by one.
The default WordPress editor does not make much sense in this case. What we needed is a preview of the font. A link to the font’s page on fonts.google.com also comes in handy.

custom meta box does the job very well. In most cases, you will use meta boxes for custom form elements to save some custom data related to the post. In fact, the content of a meta box can be practically any HTML.

function display_font_preview( $ post ) {   /* font name, for example Abril Fatface */   $ font = $ post->post_title;   /* font as in url, for example Abril+Fatface */   $ font_url_part = implode( '+', explode( ' ', $ font ));   ?>   <div class="font-preview">      <link href="<?php echo 'https://fonts.googleapis.com/css?family=' . $ font_url_part . '&display=swap'; ?>" rel="stylesheet">     <header>       <h2><?php echo $ font; ?></h2>       <a href="<?php echo 'https://fonts.google.com/specimen/' . $ font_url_part; ?>" target="_blank" rel="noopener">Specimen on Google Fonts</a>     </header>     <div contenteditable="true" style="font-family: <?php echo $ font; ?>">       <p>The quick brown fox jumps over a lazy dog.</p>       <p style="text-transform: uppercase;">The quick brown fox jumps over a lazy dog.</p>       <p>1 2 3 4 5 6 7 8 9 0</p>       <p>& ! ; ? {}[]</p>     </div>   </div> <?php }  add_action( 'add_meta_boxes', function() {   add_meta_box(     'font_preview', /* metabox id */     'Font Preview', /* metabox title */     'display_font_preview', /* content callback */     'post' /* where to display */   ); });

Tagging fonts is a long-term task with a lot of repetition. It also requires a big dose of consistency. That’s why we started by defining a set of tag “presets.” That could be, for example:

{   /* ... */   comic: {     tags: 'comic, casual, informal, cartoon'   },   cursive: {     tags: 'cursive, calligraphy, script, manuscript, signature'   },   /* ... */ }

Next with some custom CSS and JavaScript, we “hacked” the WordPress editor and tags form by enriching it with the set of preset buttons. 

How we built it: The front end part (using NuxtJS)

The goofonts.com interface was designed by Sylvain Guizard, a french graphic and web designer (who also happens to be my husband). We wanted something simple with a distinguished “search” area. Sylvain deliberately went for colors that are not too far from the Google Fonts identity. We were looking for a balance between building something unique and original while avoiding user confusion.

While I did not hesitate choosing WordPress for the back-end, I didn’t want to use it on front end. We were aiming for an app-like experience and I, personally, wanted to code in JavaScript, using Vue.js in particular.

I came across an example of a website using NuxtJS with WordPress and decided to give it a try. The choice was made immediately. NuxtJS is a very popular Vue.js framework, and I really enjoy its simplicity and flexibility. 
I’ve been playing around with different NuxtJS settings to end up with a 100% static website. The fully static solution felt the most performant; the overall experience seemed the most fluid.That also means that my WordPress site is only used during the build process. Thus, it can run on my localhost. This is not negligible since it eliminates the hosting costs and most of all, lets me skip the security-related WordPress configuration and relieves me of the security-related stress. 😉

If you are familiar with NuxtJS, you probably know that the full static generation is not (yet) a part of NuxtJS. The prerendered pages try to fetch the data again when you are navigating.

That’s why we have to somehow “hack” the 100% static generation. In this case, we are saving the useful parts of the fetched data to a JSON file before each build process. This is possible, thanks to Nuxt hooks, in particular, its builder hooks.

Hooks are typically used in Nuxt modules:

/* modules/beforebuild.js */  const fs = require('fs') const axios = require('axios')  const sourcePath = 'http://wpgoofonts.local/wp-json/wp/v2/' const path = 'static/allfonts.json'  module.exports = () => {   /* write data to the file, replacing the file if it already exists */   const storeData = (data, path) => {     try {       fs.writeFileSync(path, JSON.stringify(data))     } catch (err) {       console.error(err)     }   }   async function getData() {         const fetchedTags = await axios.get(`$ {sourcePath}tags?per_page=500`)       .catch(e => { console.log(e); return false })        /* build an object of tag_id: tag_slug */     const tags = fetchedTags.data.reduce((acc, cur) => {       acc[cur.id] = cur.slug       return acc     }, {})        /* we want to know the total number or pages */     const mhead = await axios.head(`$ {sourcePath}posts?per_page=100`)       .catch(e => { console.log(e); return false })     const totalPages = mhead.headers['x-wp-totalpages']    /* let's fetch all fonts */     let fonts = []     let i = 0     while (i < totalPages) {       i++       const response = await axios.get(`$ {sourcePath}posts?per_page=100&page=$ {i}`)       fonts.push.apply(fonts, response.data)     }      /* and reduce them to an object with entries like: {roboto: {name: Roboto, tags: ["clean","contemporary", ...]}} */     fonts = (fonts).reduce((acc, el) => {       acc[el.slug] = {         name: el.title.rendered,         tags: el.tags.map(i => tags[i]),       }       return acc     }, {})    /* save the fonts object to a .json file */     storeData(fonts, path)   }    /* make sure this happens before each build */   this.nuxt.hook('build:before', getData) }
/* nuxt.config.js */ module.exports = {   // ...   buildModules: [     ['~modules/beforebuild']   ], // ... }

As you can see, we only request a list of tags and a list posts. That means we only use default WordPress REST API endpoints, and no configuration is required.

Final thoughts

Working on GooFonts was a long-term adventure. It is also this kind of projects that needs to be actively maintained. We regularly keep checking Google Fonts for the new typefaces, subsets, or variants. We tag new items and update our database. Recently, I was genuinely excited to discover that Bebas Neue has joint the family. We also have our personal favs among the much lesser-known specimens.

As a trainer that gives regular workshops, I can observe real users playing with GooFonts. At this stage of the project, we want to get as much feedback as possible. We would love GooFonts to be a useful, handy and intuitive tool for web designers. One of the to-do features is searching a font by its name. We would also love to add a possibility to share the bookmarked sets and create multiple “collections” of fonts.

As a developer, I truly enjoyed the multi-disciplinary aspect of this project. It was the first time I worked with the WordPress REST API, it was my first big project in Vue.js, and I learned so much about typography.  

Would we do anything differently if we could? Absolutely. It was a learning process. On the other hand, I don’t think we would change the main tools. The flexibility of both WordPress and Nuxt.js proved to be the right choice. Starting over today, I would definitely took time to explore GraphQL, and I will probably implement it in the future.

I hope that you find some of the discussed methods useful. As I said before, your feedback is very precious. If you have any questions or remarks, please let me know in the comments!

The post How We Tagged Google Fonts and Created goofonts.com appeared first on CSS-Tricks.

CSS-Tricks

, , , ,
[Top]

Variable Fonts Link Dump!

There’s been a ton of great stuff flying around about variable fonts lately (our tag has loads of stuff as well). I thought I’d round up all the new stuff I hadn’t seen before.

The post Variable Fonts Link Dump! appeared first on CSS-Tricks.

CSS-Tricks

, , ,
[Top]

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.

CSS-Tricks

, , ,
[Top]

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:

https://fonts.googleapis.com/css?family=Roboto

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

https://fonts.googleapis.com/css?family=Open+Sans:400,700

And subsets:

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

So, why not…

http://fonts.googleapis.com/css?family=Creepster&font-display=swap

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.

CSS-Tricks

, ,
[Top]