Skip to main content

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...