AnApprentice
AnApprentice

Reputation: 111040

How to avoid Flash of Unstyled Text (FOUT) even with Web Font Loader?

I'm using a custom font which is large ~100kb. As you can imagine, the browser text is flashing from invisible to visible text. I therefore started using the webfontloader: https://github.com/typekit/webfontloader

However, even with this fontloader, the text still flashes. The page loads with the default font, and then once the webfontloader says the font has loaded, the CSS is triggered to use the loaded font however, it still results in the text flashing... See the codepen for example. Anytime you hard-refresh and the font needs to load, the text is flashing.

https://codepen.io/anon/pen/LQGrpL

WebFont.load({
  custom: {
    families: ['Inter UI'],
    urls: ['https://rsms.me/inter/inter-ui.css']
  }
});
body,
button {
  font-weight: 400;
  font-size: 14px;
  font-family: sans-serif;
  font-style:  normal;
}

.wf-active body,
.wf-active button {
  font-weight: 400;
  font-size: 14px;
  font-family: 'Inter UI';
  font-style:  normal;
}
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></script>
<h1>Hello World</h1>

<p>Good day to you...</p>

<button>Thank you</button>

Is there anything I can do to avoid this flashing? It's a horrible user experience.

Upvotes: 6

Views: 11749

Answers (3)

Ryan Stone
Ryan Stone

Reputation: 383

after ages messing around i came up with this:

add a class in your css file:

.showMe {
  filter: opacity(1) !important;
  transition: filter 878ms ease-in;
}

then add a javascript tag at the very end of your document just before the closing body tag.

include in the file

setTimeout(function() {
  let h1 = document.getElementsByTagName('h1')[0];
  h1.classList.add('showMe');
}, 288);

Seems to be working for me as i was having the same issue. Can play around with the timing of setTimeout to optimize which is the number at the end (in milliseconds). You could also add a transition onto this so it fades in more smoothly & also add will-change:auto; or will-change:filter; but I'll let you mess around and see what suits you. forgot to mention you need to add style="filter:opacity(0);" on the h1 in your html mark-up.

As an alterative you could have the text set to opacity 0 in your html and then use the .animate() api to fade the text in slowly when the page has fully loaded.

Upvotes: -1

Wael Assaf
Wael Assaf

Reputation: 1303

Consider experimenting with the Web Font Loader library which provides an event system that allows you to control the appearance of your page dynamically as fonts are loaded.

Here

Upvotes: 1

Giorgio Tempesta
Giorgio Tempesta

Reputation: 2059

As pointed in this link https://binarapps.com/blog/fout-with-web-font-loader/, you can hide the text until it's ready to be shown, like this:

body,
button {
   font-weight: 400;
   font-size: 14px;
   font-family: sans-serif;
   font-style:  normal;
   visibility: hidden;
}

.wf-active body,
.wf-active button {
    font-weight: 400;
    font-size: 14px;
    font-family: 'Inter UI';
    font-style:  normal;
    visibility: visible;
}

You can also add a transition on the opacity and a loader that is only visible when the body has the .wf-loading class (see the link for further explanations on these suggestions).

Upvotes: 1

Related Questions