By doing this you can create CSS rules that will only be applied when JS is available and vice versa. The trick is to make sure the class names are switched as early as possible during page load.
The first thing to to is to give the
html element a class name of
no-js in the markup:
<html lang="en" class="no-js">
However, there are some problems with that:
- It won’t happen until the DOM is ready
- jQuery needs to be downloaded and parsed first
- You want this to run before any other scripts, so you’ll need to keep track of the source order of your script files
In many cases the switch will still be fast enough that you won’t notice anything, but if you’re doing some major restyling and the browser or download speed isn’t the fastest, you can end up with content visibly changing when the page loads. You probably don’t want that.
A concrete example is changing how a site’s top navigation works on a narrow display (most often a mobile phone). If you use something similar to what I decribe in An alternative to select elements as navigation in narrow viewports, the script may not have kicked in when the page is first displayed to the user, causing an annoying jump when the menu is re-rendered.
To avoid problems like that I have started adding the following tiny inline script straight after the
title element, before anything else:
document.documentElement.className = document.documentElement.className.replace(/(\s|^)no-js(\s|$)/, '$1js$2');
This line simply replaces “no-js” with “js”. This could be reduced even further if you know for sure that the
html element will never have any other class names in the markup:
document.documentElement.className = 'js';
I prefer the first of these options since you never know when another class name is going to show up when you work in teams with other people.
Either way, the class names will now be toggled when the CSS is loaded and applied. No waiting for things to be downloaded and parsed.
Going back to my example of adapting the top navigation for narrow viewports, if the
html element has a “js” class you know that the navigation will be changed when that script is loaded and executed at some point after the DOM is ready. This means you can write your CSS accordingly to avoid (or at least reduce) redrawing and visual jumping.