Using CSS to Replace Content for JavaScript Disabled Browsers

If you’re like me, you love embellishing your projects with fancy JavaScript to give them pizzaz. But, chances are, you’ve also had some trouble finding a comfortable solution for replacing that JavaScript content for users who have (for one reason or another) disabled JS in their browser. After playing around with many possible fixes, I’ve come up with a standards-compliant, low bandwidth and easy to implement solution. And it’s probably something you weren’t expecting… CSS!

That’s right… by making use of the display:none CSS property we can serve alternate content to our non-JavaScript users without sending them to alternate pages on our site (a common, but outdated and clunky solution). So, get ready to turn off that JS in your browser (did I really just say that?) and start developing for true compatibility.

OK, this fix doesn’t rely 100% on CSS (so sue me). As a matter of fact, in order to get it working we have to add a little bit of… well… JavaScript. You may be thinking to yourself, “Wait… we have to add JavaScript to provide compatibility for users that disable JavaScript? That’s just crazy!” And you would be sorely wrong in your logic. It’s actually the least crazy fix I can think of for this problem.

Let me explain. Since JavaScript only gets run by browsers with JavaScript enabled, we can provide an extra CSS class (or id) through that script that allows us to show the JavaScript content on the page. But when the same page is loaded with JavaScript disabled, that extra CSS class doesn’t get loaded. So, by tweaking (read: “hacking”) our CSS by setting that extra class to display:none, we are essentially able to display different content for each type of visitor. Let’s take a look at the code before we go any further.

The JavaScript

/* <title> and <meta> tags */

<script type="text/javascript">
document.documentElement.className += " js"

/* everything else before <body> tag */


/* Hide this by default, show this if JS is enabled */
#needsJS { display: none }
.js #needsJS { display: block }

/* Show this by default, hide this if JS is enabled */
.js #fallback { display: none }

Seems straight forward enough, right? Now all we have to do is figure out where to put our class (or id) in our page so the JavaScript content really does get hidden for visitors with JS disabled. Here’s an example of how I have used it in the header of this page.

/* this will display when JavaScript is disabled */
<div id="fallback">
    wp_nav_menu( array('menu' => 'topnavie' ));

/* and this shows up when JavaScript is turned on */
<div id="needsJS">
    wp_nav_menu( array('menu' => 'topnav' ));

A brief explanation of my usage: Since I’m using WordPress as my platform, I am targeting two alternate, but similar WP menus created with WP 3.x through PHP. The second, topnav, relies on JavaScript to give the menu a Flash-like rollover effect (see top of this page with JavaScript on). The first, topnavie, provides a JavaScript-free version with pure CSS styling that displays just fine when JS is off. So, depending on the state of JavaScript functionality in the browser, one of these menus is always hidden, while the other is displayed in its place.

Of course, this is a fairly simple implementation of our fix. It can be far more complex, with as many “fallback” attributes as the page needs. Just remember that, in order for this to provide a consistent user experience, there should be two versions of the same content.

NOTE: As I have discovered throughout some implementations of this, a “needsJS” class is not always needed. Obviously, this depends on usage and should be carefully examined before deployment on a live page. But, when the JavaScript content to be displayed relies 100% on JavaScript to display at all, it doesn’t really need a “needsJS” class. If this just made you even more confused, I recommend always using both classes to identify each state of functionality.

As always, let me know your thoughts. And, yes, I’m ready to take some heat for saying this is a simple fix. Bring it on!

Dave Winter focuses in WordPress UI Design and WordPress Plugin Development (some have labelled him a fanatic) but has hands in many other projects, including photography and music. He's never far from a computer... or an iPad (for testing purposes, of course). If you've been to a WordCamp in Southern California, he probably already knows who you are (or maybe not - he's terrible with names). Dave currently teaches courses at California State University, Long Beach alongside his small business at (and his students think he's pretty boss).


  1. Neat, is there anything CSS can’t do?

    • Dave Winter says:

      Haha, I wish it was just that easy! But with the rapid implementation of CSS3 and HTML5, I wonder how much more CSS will be able to accomplish in the next year or so. Of course, solutions like these still require some scripting, but the web is becoming less and less reliant on it. Oops, better not smash scripting too much… I’m teaching a JavaScript class at Cal State University Long Beach this semester. Just don’t tell my students…

Let me know what you're thinking

© 2008-2020,