As a good Web Developer, you care about what happens with your page when JavaScript is disabled. The page should still be usable and the functionality that you provide should be made available to the user regardless of whether JavaScript is available or not in the browser. Taking that into account, you might want to display certain things on the page when JS is disabled, but initially hide them when JS is available. How do you deal with that problem?
Example
Say, you want to display 5 images on a page. You could think about different rendering behavior depending on whether JS is available or not:
- With JavaScript disabled, you might want to display these images in a list one after the other for the user to see right away.
- With JavaScript you might decide to put them in a nice slideshow module that appears as a modal window on the page and the user can activate by clicking on a, you probably guessed it, “View slideshow” link. But initially, when the page loads, you might want to have these images already in the markup, but not visible to the user
Markup
The markup could look something like this:
<ul class="slideshow">
<li><img src="http://farm4.static.flickr.com/3143/2659704294_1c6fdc6482.jpg" width="500" height="375" alt="View from Twin Peaks with Golden Gate Bridge in the distance" /></li>
<!-- 4 more photos you would like to show -->
</ul>
CSS
So, initially, with JavaScript disabled, you might want to display them as a list of 5 images on the page, with some nice(r) borders and some visual improvements.
<style type="text/css">
.slideshow {
list-style: none;
}
.slideshow li {
float: left;
}
.slideshow li img {
border: 3px double #ccc;
margin-right: 10px;
padding: 3px;
}
</style>
Now to present the user with a nice slideshow, we don’t want him to see the images right away, we want to hide them initially, save some browser window real estate (for some ads maybe
) and show the images upon clicking on a “View Slideshow” link. But how do we hide them initially?
Appending a class of “js” to the body element
Using the following code, placed right after the opening body tag, we are able to target content to be displayed specifically in a JavaScript enabled User Agent:
<body>
<script type="text/javascript">(document.body.className!=="") ? document.body.className += " js" : "js"</script>
<!-- rest of your page content -->
</body>
This tiny piece of JavaScript will append a class of “js” to the opening body tag with—you name it—JavaScript. So if you view “Generated Source” in Firefox, you will see something similar to this:
<body class="js">
This is amazingly helpful, cause in our CSS we can now say:
.js .slideshow {
display: none;
}
This will initally hide the list of images from the user view and we can put our slideshow module in place which will then put that list into an overlay, add navigation arrows and all the other fancy stuff.
I have to point out here that this technique is not new and was not developed by me but by some of my colleagues at Yahoo! who are much smarter than I am :-). The discussion about that technique raised by my respected colleague Mike led me to posting it here and asking my audience if they are seeing isssues with that or can even come up with a neater solution. Any thoughts?
document.documentElement.className += ” js”;
will work inside the head tag keeping the body clean. You’ll have then instead of body and it works as expected, quite well.
Cheers,
This is a classic trick, but I am not too sure about the display:none trick. We know that display:none is not displaying things and was assume that screen readers also do not find it - however not all follow this convention.
So in order to really make sure that things don’t show up at all we should remove them from the document before replacing them with the real, fancy interface.
Yoan’s right. I just tested his code across the A-level browsers, and it works, even though the body element doesn’t actually exist at the time it’s executed. I don’t understand _how_ it works, but it looks like it does.
Yoan’s Code works. The “Trick” in his Case is simply to not add the Class to the Body Element but to the root Node of the Document i.e. the HTML Element. I’m not too sure if this is the right place for the JS-Class but I like the execution speed of it as well as the Javascript being outside of the Body.
This is a great trick but I usually start out by giving body a “js-disabled”-class and then replace that with “js-enabled”.
This way you can specifically style when JS is disabled as well as when it is enabled without using the :not() pseudo-class (body:not(.js)).
I think adding a class to the root element produces invalid HTML.