cssfontsfont-facegoogle-font-api

"Variable weight" version of a TTF font not working in browser


I need to import a font (specifically in TTF for my application), and I chose the "Variable weight" version from https://fonts.google.com/specimen/Montserrat page, button "Download family". This variable weight version is called "Montserrat-VariableFont_wght.ttf".

Why doesn't the font-weight work here? There are only 2 weights: normal and bold, and not all the variable weight. Why?

Isn't it the purpose of a *_VariableFont_wght.ttf vesion to have variable weight?

@font-face { font-family: Montserrat; src: url(Montserrat-VariableFont_wght.ttf); }
* { font-family: Montserrat; }  /* for the snippet to work, we need a CDN link for this TTF file */
.w400 { font-weight: 400; }
.w500 { font-weight: 500; }
.w600 { font-weight: 600; }
.w700 { font-weight: 700; }
.w800 { font-weight: 800; }
<div class="w400">weight 400</div>
<div class="w500">weight 500</div>
<div class="w600">weight 600</div>
<div class="w700">weight 700</div>
<div class="w800">weight 800</div>

From the font README:

Montserrat is a variable font with this axis: wght

This means all the styles are contained in these files:
Montserrat-VariableFont_wght.ttf


Solution

  • This question was asked two years ago and got the same sub-optimal answer that needed a second answer to get the W3C recommended solution.

    The problem isn't that you need to use font-variation-settings, but rather that your @font-face rule didn't have a font-weight declaration.

    You can use font-variation-settings, but note that that does not work well in regard to cascading. (For details and workaround, see https://pixelambacht.nl/2022/boiled-down-fixing-variable-font-inheritance/.)

    For this reason, CSS specs advise against using font-variation-settings in any case where a specific property could be used.

    When possible, authors should generally use the other properties related to font variations (such as font-optical-sizing), and only use this property for special cases where its use is the only way of accessing a particular infrequently used font variation.

    For example, it is preferable to use font-weight: 700 rather than font-variation-settings: "wght" 700.

    https://www.w3.org/TR/css-fonts-4/#font-variation-settings-def

    The better solution is to add a font-weight declaration in the @font-face rule. With a variable font, you can specify two values to declare a range of weights.

    HTML

    <div class="w400">weight 400</div>
    <div class="w500">weight 500</div>
    <div class="w600">weight 600</div>
    <div class="w700">weight 700</div>
    <div class="w800">weight 800</div>
    

    CSS

    @font-face {
      font-family: Montserrat;
      /* declare weights giving two values to specify a range */
      font-weight: 400 800;
      src: url(Montserrat-VariableFont_wght.ttf);
    }
    
    * {
      font-family: Montserrat;
    }
    
    .w400 {
      font-weight: 400;
    }
    
    .w500 {
      font-weight: 500;
    }
    
    .w600 {
      font-weight: 600;
    }
    
    .w700 {
      font-weight: 700;
    }
    
    .w800 {
      font-weight: 800;
    }
    

    Addendum: It turns out the misunderstanding about needing to use font-variation-settings to access different weights in a variable font is widespread. The Web Almanac site just published its biennial analysis of font usage on the Web, and it turns out that 87% of usage of font-variation-settings is for the 'wght' axis. They observe,

    This somewhat surprised us, because there is no need to use the low-level font-variation-settings property to set a custom weight axis value. You can simply use the font-weight property with a custom value, for example, font-weight: 550 for a weight between 500 and 600...

    ... Similar results can be seen for the optical size, width, italic, and slant axes, which can be set using the high-level font-optical-sizing, font-stretch, and font-style properties. Using the higher level properties will make your CSS more readable and avoid accidentally disabling an axis—a common source of errors with the low-level property.