# Lazy-Loading Optional Fonts with Native Browser API

I run a site that generates music for practicing sight reading, [sightread.org](https://sightread.org). The user can pick "patterns" to work on, such as "triplets". In the settings dialog where people make this selection I can just show the option as "triplet".

![default text](/i/posts/musglyph-duck.png)

However, a friendlier way would be to show music notation. Luckily a lightweight way to do so is to use a font called `MusGlyphs` (donation suggested).

![music notation](/i/posts/musglyph-swan.png)

## What about performance? 

Since this is a user-invoked dialog, loading the font is not a pririty. Also the font uses ligatures to render musical glyphs, like for example the text `eee3` renders a three eight notes triplet. If the font fails to load, the user is left with this confusing text.

A solution is to simply put both texts "eight note triplets" and "eee3" and show one or the other, depending on whether the font is loaded. Progressive enhancement!

### Markup:

<pre class="prettyprint">
&lt;label&gt;
  &lt;input type="checkbox" name="patterns" value="eee3" title="eight note triplets"&gt;
  &lt;span class="pattern-glyph" title="eight note triplets"&gt;eee3&lt;/span&gt;
  &lt;span class="pattern-name"&gt;eight note triplets&lt;/span&gt;
&lt;/label&gt;
</pre>

### CSS:

<pre class="prettyprint">
@font-face {
    font-family: 'MusGlyphs';
    src: url('fonts/MusGlyphs-ss.woff2') format('woff2');
}

.pattern-glyph {
    font-family: 'MusGlyphs';
}

.pattern-glyph {
    display: none;
}

.MusGlyphsLoaded .pattern-glyph {
    display: inline-block;
}

.MusGlyphsLoaded .pattern-name {
    display: none;
}
</pre>
 
With this, the "eee3" text is hidden and the fallback text is shown.

### JavaScript

Then with the bit of native browser Font API we load the font and add the `.MusGlyphsLoaded` class to the `body`:

<pre class="prettyprint">
window.onload = () => {
  document.fonts.load('1em MusGlyphs')
    .then(() => document.body.classList.add('MusGlyphsLoaded'));
};
</pre>

## Magic! 

The ugly default duckling turns into a beeeeautiful swan-like font<i class="circle"><s></s></i>

