Using Web Font Loader

If you are using web fonts, you might have noticed an unpleasant moment when content is rendered before the font loads, making it re-render. Since the fonts have different heights and widths, the font being loaded or not may also affect measuring of elements and thus their placement. In some cases, if font is not yet loaded, some elements on the chart might be misaligned. Or, their position/alignment might change later on when the chart layout updates and the fonts are already loaded.

This tutorial will show how you can work around these issues using Web Font Loader.

The problem

To demonstrate the issue, let's create a very basic container with two large labels in it. For now, let's not use any web fonts.

We've added colored backgrounds to both labels so that we can see how labels are sized perfectly to match the text in it.

Now, let's instruct our web page to use some very condensed font, like "Teko Light".

@import url("https://fonts.googleapis.com/css?family=Teko:300");

body {
  font-family: "Teko";
}

Let's see how our "label-chart" looks like now:

Not cool at all, is it?

This happened because labels were created, text measured, background sized before the web font was loaded.

When the font loads, browser updates all the text on the page, including our labels, to a new font. However, the label is already sized. The text becomes shorter, but the whole Label element stays the same.

It might not matter much for stray labels, or if the custom font has comparable dimensions. However, in some cases this change will become very prominent, especially if multiple items are aligned with each other.

Say our labels were right-aligned. They would look fine with a default font. But after custom font loaded, they would be misaligned because the excess gap depends on actual length of the text.

NOTE The issue might not be prominent every time. The browser tends to cache things, including web fonts. So, if the font is already cached in you browser, it might render correctly. It helps, but does not get rid of the issue on first load, or if someone has caching disabled.

DEMO If you'd like a live version of the above "chart", click here.

The solution

That's were Web Font Loader comes in. It's a nice free JavaScript library, developed jointly by Google and Typekit folks.

In short it allows replacing custom font loading via CSS' @import with a JavaScript function.

You specify which fonts to load, and Web Font Loader takes care of it. When it's done, it can call our custom callback function.

To use Web Font Loader, we need to import or include it. Here's how you would do from Google's CDN:

<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></script>

Then in our code we just use WebFont.load() method:

WebFont.load({
  google: {
    families: ["Teko:300"]
  },
  active: function() {
    console.log("All set!");
  }
});
WebFont.load({
  google: {
    families: ["Teko:300"]
  },
  active: function() {
    console.log("All set!");
  }
});

It's as simple as that.

MORE INFO Web Font Loader has simplified setup for Google Fonts and Typekit, but you can use them with completely custom font URLs. For more information please visit WFL's own documentation.

Now that we know how to custom load fonts and know how to get notified when they are loaded, let's see how we can use that remedy our chart-label situation.

Delaying chart init

Let's make sure our chart is initialized only when all fonts are loaded:

WebFont.load({
  google: {
    families: ["Teko:300"]
  },
  active: createCharts
});

function createCharts() {
  // ...
}
WebFont.load({
  google: {
    families: ["Teko:300"]
  },
  active: createCharts
});

function createCharts() {
  // ...
}

This ensures that the charts will not even thing about starting to initialize themselves before every single web font is loaded.