Shouldn't we use <noscript> element?
Solution 1
It's better to have the default be non-javascript, and then let a javascript code overwrite with a javascript enabled page. Doesn't have to be much. Can just be a display:none;
block, which is then set to display:block;
by javascript, and vice versa for the non-js page.
Solution 2
After pondering for many days and changing my code back and forth, I think I have clearer picture now and would like to share my two cents worth on the subject before I forget.
<div id='noscript'>show non-js content</div>
<script>document.getElementById('noscript').style.display='none';</script>
<script id='required script'>show js content</script>
vs
<noscript>show non-js content</noscript>
<script id='required script'>//show js content</script>
Depending on the situation, there are three cases for consideration:
Case 1 - If required script is inline
JavaScript disabled
- Content in
<noscript>
element appears immediately, non-js content is shown - Content in
<div>
element appears immediately, non-js content is shown
JavaScript enabled
- Content in
<noscript>
element does not appear at all, js content shown - Content in
<div>
element may momentarily appear before being hidden, js content shown
For this case, using <noscript>
element is advantageous.
Case 2 - If required script is from external (third-party) source, but hiding of <div>
element is done with inline script
JavaScript disabled
- Content in
<noscript>
element appears immediately, non-js content is shown - Content in
<div>
element appears immediately, non-js content is shown
JavaScript enabled but required script is blocked
- Content in
<noscript>
element does not appear at all, nothing is shown! - Content in
<div>
element may momentarily appear before being hidden, nothing is shown!
JavaScript enabled and required script is received
- Content in
<noscript>
element does not appear at all, js content shown - Content in
<div>
element may momentarily appear before being hidden, js content shown
For this case, using <noscript>
element is advantageous.
Case 3 - If required script hides the <div>
element
JavaScript disabled
- Content in
<noscript>
element appears immediately, non-js content is shown - Content in
<div>
element appears immediately, non-js content is shown
JavaScript enabled but required script is blocked
- Content in
<noscript>
element does not appear at all, nothing is shown! - Content in
<div>
element appears, non-js content is shown
JavaScript enabled and required script is received
- Content in
<noscript>
element does not appear at all, js content shown - Content in
<div>
element may momentarily appear before being hidden, js content shown
For this case, using <div>
element is advantageous.
In summary
Use <noscript>
element if rendering of the HTML content depends on third-party scripts or if the required script is inline. Else, use <div>
element and make sure that the required script contains:
document.getElementById('noscript').style.display='none';
Solution 3
Although Tor Valamo has an elegant answer to this problem, there is an issue which may cause you to opt out of using this technique.
The problem is (usually) IE. It has the tendency to load and execute the JS a bit slower than other browsers causing it to sometimes flash the "Please Enable Your Javascript" div for a split second before it then loads the JS and hides the div.
It is annoying and to get around this you can implement the "classic". <noscript>
redirect approach.
<head>
<noscript><meta http-equiv="refresh" content="0; URL=/NO_SCRIPT_URL/ROUTE_HERE"/></noscript>
</head>
This is the most solid technique that I've come across with regards to this little nasty.
Solution 4
One useful application for noscript that I've seen is for a progressively-enhanced async loading of heavy content (especially "below the fold"). Big images, iframes, etc. can be wrapped in noscript in the HTML source, and then the unwrapped elements can be appended to the page using JavaScript after the DOM is ready. This unblocks the page and can make for a much quicker initial loading experience, especially if your interface relies on JS/JQ interactions applied after the document is ready (2 seconds vs. 6 seconds for a portfolio page I consulted on).
Solution 5
These days it seems almost every browser runs Javascript, but you can never know who is going to be accessing your site. These days even screen readers and web crawlers use Javascript, and sometimes make AJAX requests if they have to.
That said, if you're going to fall back to no-Javascript, there is a much better way than a <noscript>
tag. Simply do this in the HEAD
of your document:
<script type="text/javascript">
document.getElementsByTagName('html')[0].className += ' Q_js'; // better than noscript
</script>
With this technique, you can easily refer to the Q_js
class in your CSS to hide things. With the <noscript>
tag, the best you can hope for is to include an additional CSS file to override previous CSS. This becomes important when some elements with static content are supposed to be hidden right away (not flicker) until Javascript can make them more dynamic.
In short, the technique I suggested addresses all your cons 1-5, and I believe it's strictly better than using <noscript>
.
Jitendra Vyas
Hi, I am Jitendra a front-end developer from India specializing in web standards, accessibility, and usability based development.
Updated on July 05, 2022Comments
-
Jitendra Vyas almost 2 years
I found some good cons here:
The noscript element only detects whether the browser has JavaScript enabled or not. If JavaScript is disabled in the Firewall rather than in the browser then the JavaScript will not run and the content of the noscript element will not be displayed.
Many scripts are dependent on a specific feature or features of the language being supported in order for them to be able to run (for example document.getElementById). Where the required features are not supported the JavaScript is unable to run but since JavaScript itself is supported the noscript content will not be displayed.
The most useful place to use the noscript element is in the head of the page where it would be able to selectively determine what stylesheet and meta elements get applied to the page as the page is loading rather than having to wait until the page is loaded. Unfortunately the noscript element is only valid within the body of the page and so cannot be used in the head.
The noscript element is a block level element and therefore can only be used to display entire blocks of content when JavaScript is disabled. It cannot be used inline.
Ideally, web pages should use HTML for the content, CSS for the appearance, and JavaScript for the behavior. Using the noscript element is applying a behavior from within the HTML rather than applying it from JavaScript.
Source: http://javascript.about.com/od/reference/a/noscriptnomore.htm
I very much agree on last point. Is there a way to make and add an external
<noscript>
file? Should we place<noscript>
in the<head>
? -
mohammad over 13 yearsI recommend you no to use <noscript> , you can use the following code . <HTML> <head> <script> window.location="some-page.php"; </script> </head> <body> <p> Please active JavaScript . </p> </body> </HTML> if under any circumstance JS is not enabled , the message will be displayed otherwise user is redirected to the destination page .
-
mohammad over 13 yearsI recommend you no to use <noscript> , you can use the following code . "<HTML> <head> <script> window.location="some-page.php"; </script> </head> <body> <p> Please active JavaScript . </p> </body> </HTML>" if under any circumstance JS is not enabled , the message will be displayed otherwise user is redirected to the destination page .
-
Konerak over 13 yearsA
display:block
"your browser appears not to support JavaScript" which is set todisplay:none
by Javascript is a viable alternative toNOSCRIPT
, but you're losing the semantic information (robots don't know what you are talking about). -
Rich Bradshaw over 13 yearsFixed the formatting - just select the code and press the code button on the tool bar (or indent it with 4 spaces).
-
Sean Patrick Floyd over 13 years@Konerak true, but you could add a meta-tag for the robots, I guess
-
Tor Valamo over 13 years@Konerak yes, but what I mean is, you have a bunch of divs that are visible before your JS has removed them (for then to display them later at certain events). Whether or not the crawler sees them is irrelevant then, because they are part of the content, just not always visible for JS users.
-
user4815162342 over 12 yearsAs long as you redirect to a page that still provides the same functionality and information in other ways. Otherwise, this is really, really annoying.
-
mowgli almost 10 years$('#noscript_div').hide(); will not fire if jquery fails somehow
-
ToolmakerSteve almost 10 yearsSee stackoverflow.com/questions/3221561/… for how to avoid the flash. (Uses javascript in head tag to hide HTML tag, because that tag exists BEFORE the body is read. Then show again when document is ready.)
-
ToolmakerSteve almost 10 yearsTo be sure this approach does not cause a flash of the non-javascript version when javascript is enabled, see stackoverflow.com/questions/3221561/… for how to avoid the flash. (Uses javascript in head tag to hide HTML tag, because that tag exists BEFORE the body is read. Then show again when document is ready.)
-
random_user_name almost 10 yearsYou mention it's better.... Why is it better than
<noscript>
tags? -
Tor Valamo over 9 years@cale_b If you read the original post, you'll see a whole list of reasons.
-
Gherman over 7 yearsIf you set something to "display: none" via JS after on document ready you are going to have a blink on page open. The fallback elements are visible for a fraction of a second. That's pain. The native noscript tag doesn't blink. I have no idea how to remove the blink otherwise.
-
Gherman over 7 yearsUsage of JS by web crawlers is quite restricted still. Hiding things with JS produces a blink.
-
Gregory Magarshak over 7 yearsIt only produces a blink if your javascript is loaded after the elements. This is not hiding elements, it is adding a class to their container with Javascript added in the <head>, which is loaded before any of those elements!
-
Tor Valamo over 7 yearsYou don't even have to do it on document ready. Just do it inline script. (<div noscript></div><div myscript><script>noscript.hide, myscript.show</script> content goes here .... </div>)... as an example.
-
Stokely almost 7 yearsAnything that is hidden by default, that requires client scripting to view is to me a very dangerous proposition. I think I like the original purpose for the noscript tag which is display the page and any scripting as normal but alert the end user if javascript is disabled via noscript. This tag can be in the header btw and have CSS or links that show messaging, reroute via meta or links, etc.
-
Tigerware about 6 years@Stokely Why is it dangerous to you? Yes it needs the client to have js enabled, but thats the whole point of it. (To only show content which needs js to users who have js enabled.)
-
Stokely almost 6 yearsIt is dangerous to have HTML content ever display because of scripting. The original content and HTML should show by default regardless of scripting dependencies. The original idea behind noscript as an element was to only appear when scripting is disabled in the browser. By REVERSING that concept and now having content and noscript triggered by explicit scripts you remove the native display of these elements without scripts.
-
Raja Khoury over 5 yearsI tested this with a chrome extension thats blocks JS and doesn't work ( no redirect ) , disabling only JS from browser's settings works. Not best solution
-
Marnen Laibow-Koser about 4 yearsDownvoting. The point of something like <noscript> is to do exactly what you are suggesting: to provide a reasonable UX for users (there still are some!) who can’t or won’t use JS. There’s no JS “circus trick” here, just basic Web Standards suitable for this exact purpose. Why reinvent them and make the UX less good in the process?
-
Marnen Laibow-Koser almost 4 yearsDownvoting. Why reinvent what the standard already gives you?
-
David Spector about 3 yearsInline script elements seem to be disliked by security people and CSP. Apparently they can be used for some sort of injection attacks. They want all script to be in separate files, not sure why.