Paul Irish

I make the www fun.

Avoiding the FOUC v3.0

FOUC is an unwelcome guest to your soirée of intertube funtimes. He comes in and distracts users eyes with things they shouldn’t be seeing, and then departs ever so quickly. We don’t like him.

So you’ve likely seen code like this:

1
2
<body>
  <script>document.body.className += 'js';</script>

No good. Scripts in the body block rendering so we can do better[1]:

1
2
<head>
  <script>document.documentElement.className += 'js';</script>

Here we’ll be adding the class to the HTML element instead of the body, which we have access while we’re in the HEAD. (Naturally CSS works just fine with a html.js selector, though this doesn’t validate in HTML4)

But here’s my big hang-up:

I prefer to write unique css for the no-javascript user. I don’t want to be writing .js in front of every selector for my basic accordion/carousel/etc widgets. It’s terribly tedious. I really just want a .no-js hook.

My solution:

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

The markup has a no-js class on HTML by default but we’ll very safely change that to ‘js’ inside the head. That compressed line of javascript is basically:

1
document.documentElement.className = document.documentElement.className.replace(/\bno-js\b/,'js');

But I make it small as it’s one of the only scripts that should run in your head. Because everyone has their scripts near their </body> tag, right?

We use the same approach in Modernizr, because we want the classes to be all set on the HTML element right when the BODY content starts loading in. Fight the FOUC!

Comments