Stephen Petrey

The Most Effective Way to Avoid the FOUC

Published 3 years ago

This post was previously updated on November 01, 2018.

We all have to deal with it at some point.

The Flash Of Unstyled Content. Yuck. What a name. According to TechRepublic it has its origins documented as far back as 2001. There are a wide range of fixes. This fix however is super duper easy to implement and it’s a vanilla solution.

First, add a class to your html document

<html class="no-js">...

Then put this little guy at the very-bottom of your scripts file:

(function(H){H.className=H.className.replace(/\bno-js\b/,'js')})(document.documentElement)

And finally add this to your CSS, render content invisible until it loads:

visibility: hidden;
 opacity: 0;
}

.js {
 visibility: visible;
 opacity: 1;
}

The obvious downside to this is pretty awful. If a user comes along that doesn’t have JS enabled, your page loads but it isn’t visible. It really comes down to a pros and cons list for your users. If you’re Facebook or Google, you probably have this baked into every single product because every single product uses JS in some small or large way.

I’m not saying this is the best solution ever — I’m just saying it’s the most effective solution we have right now. This method is a Frankenstein version of Paul Irish’s approach. Which if you’re going to use this FOUC solution you better be using Irish’s DOM Based JS Routing. Then you can really iron down when and where you want JS to fire.

UPDATE: Thanks to Bert, who reminded me that I haven’t written about FOUC solutions in some time, and happy to revisit the subject.

I do have a newly updated solution. It’s not much different than above but it’s more performant.

We continue to re-use Paul Irish’s famous markup from 2009, with only marginal updates. Such as, the no-js class on the document, and script in the <head> (not in the body, nor in the footer, this needs to be parsed right-away):

<html class="no-js">
<head>
  <script>(function(H){H.className=H.className.replace(/\bno-js\b/,'js')})(document.documentElement)</script>
...

Next, we write CSS for the no-js state:

.no-js {
 visibility: hidden;
 opacity: 0;
}

.js {
 visibility: visible;
 opacity: 1;
}

And Bob’s your uncle! Same as before, but only slightly revised for performance. Enjoy!

UPDATE: There’s more than one way to skin a cat as they say. Many thanks to elektrotype, who came up with this brilliant solution, which works great for no-js users. In-short, they won’t see a white-screen if they don’t have JS enabled: