Shouldn't we use <noscript> element?

74,127

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>.

Share:
74,127
Jitendra Vyas
Author by

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, 2022

Comments

  • Jitendra Vyas
    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
    mohammad over 13 years
    I 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
    mohammad over 13 years
    I 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
    Konerak over 13 years
    A display:block "your browser appears not to support JavaScript" which is set to display:none by Javascript is a viable alternative to NOSCRIPT, but you're losing the semantic information (robots don't know what you are talking about).
  • Rich Bradshaw
    Rich Bradshaw over 13 years
    Fixed the formatting - just select the code and press the code button on the tool bar (or indent it with 4 spaces).
  • Sean Patrick Floyd
    Sean Patrick Floyd over 13 years
    @Konerak true, but you could add a meta-tag for the robots, I guess
  • Tor Valamo
    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
    user4815162342 over 12 years
    As 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
    mowgli almost 10 years
    $('#noscript_div').hide(); will not fire if jquery fails somehow
  • ToolmakerSteve
    ToolmakerSteve almost 10 years
    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.)
  • ToolmakerSteve
    ToolmakerSteve almost 10 years
    To 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
    random_user_name almost 10 years
    You mention it's better.... Why is it better than <noscript> tags?
  • Tor Valamo
    Tor Valamo over 9 years
    @cale_b If you read the original post, you'll see a whole list of reasons.
  • Gherman
    Gherman over 7 years
    If 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
    Gherman over 7 years
    Usage of JS by web crawlers is quite restricted still. Hiding things with JS produces a blink.
  • Gregory Magarshak
    Gregory Magarshak over 7 years
    It 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
    Tor Valamo over 7 years
    You 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
    Stokely almost 7 years
    Anything 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
    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
    Stokely almost 6 years
    It 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
    Raja Khoury over 5 years
    I 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
    Marnen Laibow-Koser about 4 years
    Downvoting. 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
    Marnen Laibow-Koser almost 4 years
    Downvoting. Why reinvent what the standard already gives you?
  • David Spector
    David Spector about 3 years
    Inline 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.