My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.

Tuesday, September 18, 2007

noscript tag behaviour and head conflicts

In this Web 2.something era there's a big problem with noscript tag and I wonder what does W3 think about them.

noscript and its standard implementation

This tag is really useful to increase page informations or accessibility, allowing developers to show an alternative content if user has not JavaScript enabled or his browser doesn't support other kind of tags.

<script type="text/jvascript">doStuff()</script>
<noscript>Your browser can't do my Stuff</noscript>

This is a basic example of noscript usage and expected behaviour is that every JS compatible browser will try to execute code insde script tag while every JS disabled or not compatible browser will show an alternative information.

So, what's wrong with noscript ?

When a browser is JS compatible ignores totally noscript tag.
It doesn't render its informations, just "jump" after the end of this tag.
At the same time, if a browser is not compatible with tag used before noscript, it will ignore totally every kind of its informations such src, code execution plugin initializzation or other things.

In few words, noscript is a WAI-AAA but at the same time has too many limitations that are totally against the real accessibility.

In fact, (X)HTML doesn't accept a noscript tag inside head one and at the same time doesn't accept external resources inside noscript tag.

This simply means that You can't include a dedicated stylesheet or link tag inside noscript one so every navigator need to download entire page, included noscript, even if it'll never use its informations.

At the same time is not possible to run a UI dedicated style using JavaScript inside head tag, the right place to put style, link and / or script tags.

All these things mean that a page can't separe, respecting W3 standards, content for JS enabled browsers and other, simply because every navigator has to download at least two kinds of CSS, even if the biggest one, dedicated for example to render correctly YUI!, Dojo, Ext, Interface, Moo or every other client libraries that today are strongly used inside a big range of sites.

I'm obviously talking about external resources and DOM with a goal to make page smaller than ever downloading only useful resources: JS + dedicated CSS for enabled browsers, dedicated CSS for browsers without JS support.

I read about new XHTML 2.0 handler tag, but the question, now, is:
will W3 ever remove from its validator program the error about noscript inside head tag?

Can anyone explain me why noscript can't be after a script inside head and why noscript can't contain in every part of page an external resource?

Please, tell me if there's a way to solve this problem or if ignore them is the only one solution just because every browser support noscript tag inside head one and load its external resources correctly, thank You.

<script type="text/javascript"><!--//
// this file should be download only by JS enabled browsers
var link = document.createElement("link");
link.rel = "stylesheet"; = "screen";
link.href = "myBigLibrary.css";
title="more speed for everyone"


Anonymous said...

Totally agree. NOSCRIPT should be valid inside the HEAD section. Currently I'm implementing NOSCRIPT in the head to define different style sheets for users with or without javascript, even though it doesn't validate.

Quatrux said...

I agree with you, I also noticed that noscript tags does not validate anymore in the head, which is quite annoying, I understand that it shouldn't validate in p tags or etc. but in head? :( I don't see any reason..

mcmlxxii said...

Yes I have to agree this is as fatheaded a decision as I have encountered so far.

Anonymous said...

Indeed the noscript should be valid inside the head.
A workaround is to include an stylesheet in the head by default, and let an script remove it. Though this won't work in every occasion.

Anonymous said...

I agree noscript should be valid in head, but i have sacrificed this in order to maintain valid html

Anonymous said...

here is a fix. hope it works for you.

fix for noscript in html head tag

Gaurav Talwar said...

I am in a catch 22 .. I want to direct user to a new page by adding refresh and new url in meta tag in noscript in head. Now this is not valid XHTML and if i add this in body, i cant have meta .. So what do i do :(

Anonymous said...

The noscript tag IS VALID in head tag. The validator is buggy. There is not a single word in standard specs that would say that noscript is invalid, so every browser do support it in head tag. See Document Head section of HTML 4.01 Document Type definition, where noscript is explicitly mentioned in head tag entity -

So, use noscript nested in head tag freely

Anonymous said...

You can put the NOSCRIPT tag in the head section of xhtml if you put it in a OBJECT tag but after that it still does not accept external css as valid

digibee said...

Fortunately for me, a commented STYLE block inside an OBJECT inside a NOSCRIPT inside a HEAD seems to work in XHTML and validates:

<object><script src="scripts/css_browser_selector.js" type="text/javascript"></script>
<noscript><!-- <style type="text/css">.gallery li a:hover img.polaroid { visibility:visible !important; }</style> --></noscript></object>

Sorry to hear external style sheets don't seem to work. I'd be tempted to try @import in a commented STYLE BLOCK as above when I have a minute.

Chad Musgrove said...

Placing object around the noscript tag allows it to validate - thank you for the suggestion.

Andrea Giammarchi said...

Chad, that is a hack, not a real solution to the intrinsic problem :(

Laeti said...

Hello! After getting help from your comments I thought I would share with you the simple trick I used. My problem was that I needed to provide a few alternative styles for when the website is viewed without javascript. Embedding style in an object helped for W3C validation but embedding style in noscript is illegal as well. Therefore I took advantage of the attribute "title" of style tags, which allows me to retrieve it very easily and as first thing, then simply remove it with javascript.

Head [r] said...

Idea: I have few css for different screen res. So I can first link to default «non-js-browser» css, then js valid one for override.

Is I'm right or where I am?

Thumbnail said...

I currently use this:
<style type="text/css" id="noscript">
@import "./css/noscript.css";

in combination with:
$(function() {

with works great :D