JavaScript aware CSS

By Mattias Kihlström

Let your CSS know if JavaScript is enabled or disabled by first adding a class to the html root element and then changing it using JavaScript.

Why?

You want to give the best possible experience to both JavaScript and non-JavaScript users. For instance you might have a partially collapsed text with a JavaScript-based "Read more" button. Of course you want the whole text to be visible if JavaScript is disabled. At the same time you want to avoid the flickering that might occur if JavaScript is used to hide the text after the page has loaded. Chances are then that a CSS selector expression that only triggers if JavaScript is enabled will make you feel better.

How?

In the following example a border is set on one of the two paragraphs in the body. The first one gets a blue border if JavaScript is enabled and the second one gets a red border if JavaScript is disabled (for illustrative purposes only).

<html class="noscript">
  <head>
    <title>JavaScript aware CSS - example 1</title>
    <script>
      document.documentElement.className = 'script';
    </script>
    <style>
      .script .one { border: 3px solid #00f; }
      .noscript .two { border: 3px solid #f00; }
    </style>
  </head>
  <body>
    <p class="one">Blue border when JavaScript is enabled.</p>
    <p class="two">Red border when JavaScript is disabled.</p>
  </body>
</html>

You can try it out here. But what if you already have another CSS class on the html tag? Then you will have to alter the script part to something like this instead:

document.documentElement.className = 
document.documentElement.className.replace( 'noscript', 'script' );

The second example is perhaps i bit more useful. In it you will see the use of a "Read more" button if JavaScript is enabled and the whole text if JavaScript is disabled. jQuery is used in order to simplify the code and to achieve the sliding effect.

<html class="noscript another-class">
<head>
<title>JavaScript aware CSS - example 2</title>
<script>
	document.documentElement.className =
		document.documentElement.className.replace( 'noscript', 'script' );
</script>
<style>
	body { font-size: 1.5em; margin: 5% 15%; }
	input { font-size: 100%; }
	.script #more { display: none; }
</style>
</head>
<body>
<p>Lorem ipsum dolor sit amet ... erat purus a massa.</p>
<p id="more">Sed ac magna in ... in euismod risus.</p>
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script>
var more = 'Read more';
var less = 'Read less';
$( 'body' )
	.append( '<input type="button" value="' + more + '">')
	.click( function() {
		$( '#more' ).slideToggle( 'fast' );
		this.value = less !== this.value ? less : more;
	})
);
</script>
</body>
</html>

What else can you think of that would benefit from JavaScript aware CSS? Could it be used to style a noscript element with display:block? Or maybe provide a stand in for a JavaScript driven mega menu by using the :hover pseudo element only when JavaScript is disabled?

Anything is possible.