I take two versions of Open Sans from Google Fonts' servers. Regular and a bold one. As soon as page loads, the font is shown nicely. The idea is something like this

a.link {
    font-weight: 400;
}

a.link.selected {
    font-weight: 800;
}

There's jQuery snippet that says that as soon as a.link is clicked, it applies .selected to them. Here's the problem. When page finishes loading and the fonts show normally, and then you click the link. The text in link flickers to default font (Times New Roman) for 100ms and then switches to bold version of Open Sans. It's probably because it doesn't have this font in cache and it takes it's time to load the bold version. I can reinstantiate this bug only if I clean cache. Refreshing page without clearing cache does not show the "bug".

Is there a way to load fonts so that when class is being applied, it does not flicker back to fall-back font?

Dani AI

Generated

The flicker you see is the browser showing a fallback font while the bold webfont is still being fetched. That matches what described: the regular weight is present but the 800 weight isn’t downloaded until you click, so the UA briefly paints a system face and then swaps in Open Sans bold. There are three practical ways to stop it.

First, make the bold weight download early. Either request both weights up front (so the browser fetches 400 and 800 at page load) or explicitly preload the bold font file so it is prioritized by the network stack. Example preload (replace the href with your actual font file path and keep crossorigin if it’s on a different origin):

<link rel="preload" href="/fonts/opensans-800.woff2" as="font" type="font/woff2" crossorigin>

If you host fonts via @font-face, add font-display to control swapping behavior (for example font-display: swap or block depending on your preferred tradeoff).

Second, use the font-loading API or a loader to ensure the bold face is ready before toggling the class. You can use the built-in API without external libs:

document.fonts.load('800 16px "Open Sans"').then(function() {
  // bold is loaded — safe to add .selected
});

Or, as a lightweight hack, create an off-screen element styled with the bold weight on initial load to force the browser to fetch that weight in the background.

Third, higher-level options: use FontFaceObserver or the Google loader (as suggested) to coordinate loads, or switch to a variable font so changing weight doesn’t trigger a second file fetch. Hosting WOFF2 files locally and using preload + correct CORS headers gives you the most control but increases your responsibility for caching and updates.

Trade-offs: preloading increases initial bytes; blocking rendering (font-display: block) prevents FOUT but can cause invisible text. For most cases the best balance is to request both weights up front or preload the bold weight (or use document.fonts.load) so the click doesn’t trigger a network fetch and the flicker disappears.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.