Handling initial display states for jQuery-enhanced pages
When building a jQuery-enhanced site (or using any other JavaScript library, for that matter) I find one of the tasks I use jQuery for is to set the initial display states of various elements on the page.
For instance, you may have some elements that should only be displayed if JavaScript is enabled; and some which should be hidden. But what do you do to avoid the flash of unwanted content which may appear before various libraries load? Here’s my solution…
For my example, I’ll have two DIVs, called “basic” and “enhanced”. Of course, in real life your requirements will most likely be more complex than this:
<div id="basic">
An element which only shows if JavaScript IS NOT enabled
</div>
<div id="enhanced">
An element which only shows if JavaScript IS enabled
</div>
The first thing to do is set the default, non-JavaScript state in CSS:
#basic {
display: block;
}
#enhanced {
display: none;
}
Previously, my hide/show method would use jQuery:
$(function(){
$('#basic').hide();
$('#enhanced').show();
});
…and this would work, but there is the overhead of loading everything before the jQuery ready() function fires. This can often cause a flash of the basic-state content to show, and elements to jump around on the page. Also, there is (slight) added jQuery processing overhead if you’re handling multiple elements.
So the method I now use – which I’m sure I picked up in part from somewhere else, but I can’t find anything by Googling! – is to include the following script on each page:
<script type="text/javascript">
document.getElementsByTagName('html')[0].className = 'js';
</script>
It will run immediately the HTML document is processed, regardless of how long the rest of the page takes to load, and simply sets a class of “js” on the HTML element. You can then use CSS to handle what should be shown or hidden:
html.js #basic {
display: none;
}
html.js #enhanced {
display: block;
}
…and the manipulation will be there as soon as the CSS is loaded.
I’ve put this tip up here mostly as a reminder to myself for the future, but I hope other people will find it useful too…
That is a good tip, thanks for posting it.
I think you mean either display:none or visibility:hidden in your CSS example, and not display:hidden ;-)
Thanks Sam, of course I mean display: none... Brain was still thinking of the jQuery hide() method.
I've updated the post with the correction now.
Nice one, very useful.
Just wanted to drop a note of thanks for posting about this technique. I found this just at the right moment to help us with the launch of PBS KIDS, where we were trying to deal with the extreme ugliness of having all of our no-flash content visible for a moment before our Flash content was written in.
That's really a nice technique. With as much JS development as I do, I'm surprised I never thought of this. That's going to DRAMATICALLY decrease my code time. :)
Thanks for your posting!
I'm using your method, and it works great!