DOM flickering occurs when you hide elements using JavaScript and there’s a noticeable delay between the page being loaded and the element actually hiding. This usually happens because you’re handling the removal upon the onload
event; this is generally a bad idea – this event will not fire until everything has loaded, including images!
It’s considered better practice to use one of the various domReady
abstractions available. Unfortunately, this won’t always work either, especially with large DOM structures! One method I’ve been using recently to avoid the flicker is to add a class to the body
element as soon as it exists, thereby making it possible to affect the styling of these elements before they even exist within the DOM! An example:
<!-- SIMPLIFIED --> <html> <head> <style type="text/css"> body.js .nojs { display: none; } </style> </head> <body> <!-- BODY element exists! --> <script> document.body.className += ' js'; </script> <div class="nojs"> ... No flicker! </div> </body> </html> |
Or, more cleanly:
<!-- SIMPLIFIED --> <html> <head> <style type="text/css"> html.js .nojs { display: none; } </style> <script> // Add class to <html> element document.documentElement.className += ' js'; </script> </head> <body> <div class="nojs"> ... No flicker! </div> </body> </html> |
How do you solve the “flicker” problem?
Thanks for reading! Please share your thoughts with me on Twitter. Have a great day!
I’ve used a similiar technique, but like this:
I use this method, just because when I’m working on an application that requires JS (such as an intranet app) I don’t even need the JS to write the style–I can just hard code it into the style sheet. (It’s important to note that I spend 99% of my time working on applications that require JS.)
Ah, sorry about that Dan! WordPress ate all your HTML… Could you email me a gist of it? (then I’ll add the link to your comment)
In an ideal world the element should already be hidden via CSS – if your going to hide said element onLoad why should it be visible in the first place?
Either way, you still demonstrate a useful way of triggering this before onLoad and any domReady function,
@Phunky – If you do that, people who have CSS enabled and JS disabled would never see those elements. And there are more of those than you think.
You’re quite right Bryan, but it’s all relative to the reasons why your hiding it in the first place. I would expect if you even need to worry about doing something like this you will already be heavily dependent on JS being enabled.
@James:
It was essentially the same code you posted, but I just write the .js-hide CSS class using JS. That way browsers with JS enabled won’t see the flicker, when JS is disabled the element shows as normal.
You could also just place the style block inside noscript tags if you wanted to avoid document.write() altogether.
What I meant to say about noscript, is that you’d declare a default style which like:
Then inside a noscript block, you’d do:
You could also use visibility instead if you plan on using this technique w/non-block elements.
Since the
body
tag isn’t required, I recently started writing that one out with JavaScript:...</head><script>document.write('<body class=yay-and-hooray-js-is-on>')</script><h1>...</h1>
. Or is that too hacky? 🙂Hi James,
nice blog entry, glad you covered this one. The name ‘Dom flicker’ is probably more descriptive, I find this phenomenon has started being referred to as ‘FOUC’ or Flash of unstyled content, whereas really it should be flash of mis-styled content – but that’s not as catchy.
Personally, I go with your method of not using document.write (the horror, the horror) but just adding in a bit of script that adds the class to the HTML tag, then all your css can actually go after that bit of script, I wrote a walk through back in January to explain:
Avoiding FOUC
The solution I’ve been using now is as follows:
That script line is more or less a minified version of:
I, like you, really enjoy the ‘nojs’ approach so you can explicitly write CSS for the un-enhanced case.
Great post! I forgot that you can edit the dom after you know an element exisits vs. waiting for domReady or similar event. Will def. use this moving forward.
What we tend to do is have a separate style sheet called js.css and inside that we have all of our js styled content.
We then on load add the class to say the body or even the html element, and add the js.css file using JavaScript.
Then if the js class exists all content is styled using the js.css stylesheet. If this does not exist content is styled as normal. So this way everything is still available to our users.
You do still notice a slight flicker even using this method but it’s much quicker than using js to hide elements on the fly initially.