skip to Main Content

Problem: I’m trying to get a Google variable font to work (I’m okay with the non-variable ones).

I am new to the mysterious world of Google fonts, and it seems there are a lot of opinions out there on how they should be implemented.

Per suggestions around in the interwebs, if I enter this in my browser to test my <link> tab in my <head>:

https://fonts.googleapis.com/css2?family=Roboto+Flex:slnt,wdth,[email protected],25..150,200..700&display=swap

and I get a bunch of these:

/* latin-ext */
@font-face {
  font-family: 'Roboto Flex';
  font-style: oblique 0deg 10deg;
  font-weight: 200 700;
  font-stretch: 25% 150%;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/robotoflex/v26/NaNeepOXO_NexZs0b5Qrz. . ..woff2) format('woff2');
  unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, . . . U+1E00-1E9F;
}

I thought those were to go at the top of my .css file. But it doesn’t seem to make any difference. In fact, even if I leave it out for the non-variable fonts, as long as my <link> tag checks out, they work fine.

The variable font does not. Here’s my .css:

  font-family: "Roboto Flex", Arial;
  font-weight: 400;
  font-stretch: 150%;

What am I not getting?

2

Answers


  1. Should be pretty easy if you just accept the defaults and follow Google’s instructions. I prefer the @import in the CSS over the <link> in the HTML.

    @import url('https://fonts.googleapis.com/css2?family=Roboto+Flex:opsz,[email protected],100..1000&display=swap');
    
    body {font-family: 'Roboto Flex';}
    
    p:nth-child(1) {font-weight: 200;}
    p:nth-child(2) {font-weight: 300;}
    p:nth-child(3) {font-weight: 400;}
    p:nth-child(4) {font-weight: 500;}
    p:nth-child(5) {font-weight: 600;}
    p:nth-child(6) {font-weight: 700;}
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
    <p>Maecenas tempor nunc mauris, sit amet placerat tortor lobortis dapibus.</p>
    <p>Nam lectus eros, maximus ac magna vel, congue consequat eros.</p>
    <p>Fusce id pretium diam. Cras sit amet pharetra ante.</p>
    <p>Sed quis commodo quam, vel facilisis ipsum.</p>
    <p>Vestibulum sodales iaculis arcu, et fringilla nisi ullamcorper sed.</p>
    Login or Signup to reply.
  2. Whenever you need to load a "custom font" you need @font-face rules.
    The syntax is based on web-standards.

    In other words the CSS retrieved via google-fonts-API doesn’t have a proprietary format/syntax and is not different from a CSS you would need to load fonts locally (from your web server).

    The main difference: the CSS is dynamic when loading from google’s API. Most importantly google server will apply agent detection to deliver the most suitable font files. You can easily test this by comparing the returned CSS output in Firefox vs a Chromium/blink or a Safari/Webkit browser.

    Unfortunately, this approach has its flaws: for instance modern Opera versions (also Chromium/blink) are still detected as not supporting variable fonts.

    Wether you add a <link> element in your header or a @import rule in your CSS doesn’t really matter with regards to the returned CSS (albeit the @import approach is considered to be less ideal in terms of loading speed and caching).

    https://fonts.googleapis.com/css2?family=Roboto+Flex:slnt,wdth,[email protected],25..150,200..700&display=swap
    

    Is a dynamic query loading the variable font

    • "Roboto Flex"
    • including the slant, weight and width design axes
    • while setting the font-display property to "swap"

    You could as well copy the code and paste it to your own page CSS file.
    You could also download all font files and replace the src properties accordingly. That’s basically what you need to do as a web designer in Europe to be GDPR compliant (no cdn resources).

    let sliders = document.querySelectorAll('input[type=range]');
    
    sliders.forEach(slider => {
      slider.addEventListener("input", (e) => {
        let weight = +wght.value;
        let width = +wdth.value;
        let slant = +slnt.value;
        preview.style.fontVariationSettings = `"wght" ${weight}, "wdth" ${width}, "slnt" ${slant}`
      });
    })
    /* latin */
    
    @font-face {
      font-family: 'Roboto Flex';
      font-style: oblique 0deg 10deg;
      font-weight: 100 1000;
      font-stretch: 25% 151%;
      font-display: swap;
      src: url(https://fonts.gstatic.com/s/robotoflex/v26/NaPccZLOBv5T3oB7Cb4i0zu6RME.woff2) format('woff2');
      unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
    }
    
    main {
      font-family: 'Roboto Flex';
      font-size: 10vmin
    }
    <label>width: <input id="wdth" type="range" min="25" max="151" value="100" step="0.1"></label>
    <label>weight: <input id="wght" type="range" min="100" max="1000" value="400" step="0.1"></label>
    <label>slant: <input id="slnt" type="range" min="-10" max="0" value="0" step="0.1"></label>
    
    <main>
      <p id="preview">Hamburgefons</p>
    </main>

    Worth noting "Roboto Flex" provides quite a few design axes – that’s why the font-face appears more complex

      font-style: oblique 0deg 10deg;
      font-weight: 100 1000;
      font-stretch: 25% 151%;
    

    Notice the properties with 2 values – specifying the possible range.

    So there is no mystery =)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search