What is the purpose of the HTML "no-js" class?
Asked Answered
T

7

553

I notice that in a lot of template engines, in the HTML5 Boilerplate, in various frameworks and in plain php sites there is the no-js class added onto the <HTML> tag.

Why is this done? Is there some sort of default browser behavior that reacts to this class? Why include it always? Does that not render the class itself obsolete, if there is no no-"no-js" case and html can be addressed directly?

Here is an example from the HTML5 Boilerplate index.html:

<!--[if lt IE 7 ]> <html lang="en" class="no-js ie6"> <![endif]-->
<!--[if IE 7 ]>    <html lang="en" class="no-js ie7"> <![endif]-->
<!--[if IE 8 ]>    <html lang="en" class="no-js ie8"> <![endif]-->
<!--[if IE 9 ]>    <html lang="en" class="no-js ie9"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--> <html lang="en" class="no-js"> <!--<![endif]-->

As you can see, the <html> element will always have this class. Can someone explain why this is done so often?

Treillage answered 17/7, 2011 at 14:35 Comment(0)
L
526

When Modernizr runs, it removes the "no-js" class and replaces it with "js". This is a way to apply different CSS rules depending on whether or not Javascript support is enabled.

See Modernizer's source code.

Ladylike answered 17/7, 2011 at 14:37 Comment(17)
There's another great write-up on it here: alistapart.com/articles/…Conium
Since Modernizr replaces "no-js" with "js", you can use this as a way to do the equivalent of an if/else statement in your CSS code. For example, .myclass { /* CSS code for all versions of your page goes here */ }, .js .myclass { /* This CSS code will only show up if JS is enabled */ } and .no-js .myclass { /* This CSS code will only show up if JS is disabled. */ }. Hope this helps. -NickPistoleer
it's kind of annoying, because the html tag shouldn't have any class name assigned to it.Foiled
@Ringo: HTML 5 specifies that any element may have a class attribute. Although HTML 4 technically doesn't, no browser chokes on it; even the ones that don't support it just ignore it, and i haven't seen one of those browsers in years.Geisel
wouldnt it be the same to add it to the <body> tag and save trouble?Enteron
@Juan that would potentially create more trouble. Using the class with body as opposed to any other element would be done differently: (body.js vs .js p). Also, as cHao pointed out, putting it on the body does not in fact save any trouble.Walcott
@ZachL Huh? what's wrong with putting it on the body and using the same css code ( .js p )Wivern
@Wivern Imagine you want to add padding to the <body> element. You would have to do body.js{padding:...} whereas any other element you can do .js element {padding:...} (.js body... will not work) It's a minor point, but it's just a little bit more consistent, and by extension, better.Walcott
@ZachL I realize I must be smoking crack here, but it seems to me that .js { padding: ...} is just fine since you know as the one who implemented it that body = .js. More directly to your point, it seems you are claiming that body.js is worse than .js body which I am not following...Wivern
@ZachL Furthermore, if your only argument is that every time you reference .js it should remain consistent and include a subclass or subelement like .js element you are acting like noone ever adds css to the html element. Think css resets and default styles, so the same logic applies there. I really am not seeing where you are coming from. As long as you know the root element is body there is no harm in this. Your only issue would be if you absolutely had to add styles to the html element and only when the html element had .js or .no-jsWivern
@Wivern what added benefit to you get by putting it on <body> instead?Walcott
@ZachL I don't see any added benefit, but certainly there is nothing wrong with putting it on the <body> like you were claiming. You get the same benefits as putting it on <html>Wivern
@ZachL It's not really a big deal, but putting the class attribute on the html tag would have a small benefit of being HTML<5 spec compliant. I'm not at all swayed one way or the other by any of the other arguments on the matter.Delorsedelos
It's worth mentioning html5-boilerplate puts it on <html> and no issue has ever been reported against that. Somehow putting it on <html> has become an established practice and people immediately know what it is and what it does. In the end, deviating from that practice just raises more questions.Ladylike
That's a good point. Changing it now would create unnecessary problems with negligible benefitDelorsedelos
@Geisel do you know what is <html class="default"> mean ?Nostradamus
@stom: It means the document element (basically the root node) has a class named "default". That's it. The browser doesn't care much about classes; they're to make scripts and stylesheets easier to use. The only changes to the functionality or appearance of the page, are the ones that your JS and/or CSS cause.Geisel
W
119

The no-js class is used by the Modernizr feature detection library. When Modernizr loads, it replaces no-js with js. If JavaScript is disabled, the class remains. This allows you to write CSS which easily targets either condition.

From Modernizrs' Anotated Source (no longer maintained):

Remove "no-js" class from element, if it exists: docElement.className=docElement.className.replace(/\bno-js\b/,'') + ' js';

Here is a blog post by Paul Irish describing this approach: http://www.paulirish.com/2009/avoiding-the-fouc-v3/


I like to do this same thing, but without Modernizr. I put the following <script> in the <head> to change the class to js if JavaScript is enabled. I prefer to use .replace("no-js","js") over the regex version because its a bit less cryptic and suits my needs.

<script>
    document.documentElement.className = 
       document.documentElement.className.replace("no-js","js");
</script>

Prior to this technique, I would generally just apply js-dependant styles directly with JavaScript. For example:

$('#someSelector').hide();
$('.otherStuff').css({'color' : 'blue'});

With the no-js trick, this can Now be done with css:

.js #someSelector {display: none;}
.otherStuff { color: blue; }
.no-js .otherStuff { color: green }

This is preferable because:

  • It loads faster with no FOUC (flash of unstyled content)
  • Separation of concerns, etc...
Walcott answered 13/9, 2012 at 16:22 Comment(3)
The Modernizr version using a RegExp is safer (and likely faster) though.Macaluso
@Macaluso - could you maybe expand on that a bit? How exactly is it safer?Walcott
@ZachL The regexp version (with \b) doesn't match something like anno-jsus, the other changes it to anjsus. no-js is not a typical substring of any class name, but still in this respect it's "safer" with \bs.Alcuin
B
42

Modernizr.js will remove the no-js class.

This allows you to make CSS rules for .no-js something to apply them only if Javascript is disabled.

Baleful answered 17/7, 2011 at 14:37 Comment(0)
T
17

The no-js class gets removed by a javascript script, so you can modify/display/hide things using css if js is disabled.

Tiemannite answered 17/7, 2011 at 14:38 Comment(3)
You said "The no-js class gets removed by a javascript script". So how Javascript works (Able to remove 'no-js' class) if it 's disabled. Could you give me a clear?Callosity
You're right and this is actually the point: If JavaScript is disabled, the class will stay and you can for example show some html part using CSS to warn the user about it. .no-js #js-warning {display: block;}Tiemannite
Be aware, JS errors may occur after Modernizr has done this so its not a foolproof way of testing JS is functioningBirth
O
15

This is not only applicable in Modernizer. I see some site implement like below to check whether it has javascript support or not.

<body class="no-js">
    <script>document.body.classList.remove('no-js');</script>
    ...
</body>

If javascript support is there, then it will remove no-js class. Otherwise no-js will remain in the body tag. Then they control the styles in the css when no javascript support.

.no-js .some-class-name {

}
Overdue answered 1/8, 2014 at 5:40 Comment(0)
M
5

Look at the source code in Modernizer, this section:

// Change `no-js` to `js` (independently of the `enableClasses` option)
// Handle classPrefix on this too
if (Modernizr._config.enableJSClass) {
  var reJS = new RegExp('(^|\\s)' + classPrefix + 'no-js(\\s|$)');
  className = className.replace(reJS, '$1' + classPrefix + 'js$2');
}

So basically it search for classPrefix + no-js class and replace it with classPrefix + js.

And the use of that, is styling differently if JavaScript not running in the browser.

Monoplane answered 10/6, 2017 at 9:27 Comment(0)
E
1

The no-js class is used to style a webpage, dependent on whether the user has JS disabled or enabled in the browser.

As per the Modernizr docs:

no-js

By default, Modernizr will rewrite <html class="no-js"> to <html class="js">. This lets hide certain elements that should only be exposed in environments that execute JavaScript. If you want to disable this change, you can set enableJSClass to false in your config.

Emory answered 31/10, 2018 at 19:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.