Friday, August 1, 2008

The <noscript> can't follow <script> everywhere - the unfortunate life as a block level element

pencil icon, that"s clickable to start editing the post

A new day and a new finding on the good ol' (x)html. I've just all ways assumed that the <noscript> tag could be used with <script> - but I was wrong, taught by doing validation myself! The <noscript> tag is restricted to block level wheres <script> can be used inline as well. The implication is that if you care for validity you'll have to look out for it, though the interaction between scriptet and non-scriptet parts can vary greatly and probably you'll all ways be able to find a way thorugh.

I'll start the investigation by getting the terms defined. In the HTML 4.01 specification section 7.5.3 " Block-level and inline elements":

Certain HTML elements that may appear in BODY are said to be "block-level" while others are "inline" (also known as "text level"). The distinction is founded on several notions:

Content model
Generally, block-level elements may contain inline elements and other block-level elements. Generally, inline elements may contain only data and other inline elements. Inherent in this structural distinction is the idea that block elements create "larger" structures than inline elements.
By default, block-level elements are formatted differently than inline elements. Generally, block-level elements begin on new lines, inline elements do not. For information about white space, line breaks, and block formatting, please consult the section on text.
For technical reasons involving the [UNICODE] bidirectional text algorithm, block-level and inline elements differ in how they inherit directionality information. For details, see the section on inheritance of text direction.

so the real problem for <noscript> is not that it's a block-level element, since that makes it possible to embed full markup inside, but rather that it's not an inline element since that restricts where it can placed itself.

The DTD's for XHTML has the link to DTD for XHTML 1 Transitional, where the definition for the script tags are defined:

<!-- these can occur at block or inline level -->
<!ENTITY % misc.inline "ins | del | script">

<!-- these can only occur at block level -->
<!ENTITY % misc "noscript | %misc.inline;">

For a longer diskussion see for example the thread <:noscript> validation with XHTML problem.

An example -

As an example let's look at which is almost free of validations errors etc., but this &noscript> thingy. A validation of the indexpage with the w3c validator gives Failed validation, 13 Errors. The first error is described as Error Line 1, Column 1985: document type does not allow element "noscript" here; assuming missing "object" start-tag with reference tto this snippet:

…><![CDATA[&nbsp;]]></script><noscript><link href="/styles/main.css" media="sc..

This problem is another variant of this problem. The <noscript> naturally can't go into the head section since markup here (in case the agent doesn't support scripting) would bread the document model. In the annotated DTD this is defined here:

<!--================ Document Head =======================================-->

<!ENTITY % head.misc "(script|style|meta|link|object|isindex)*">

<!-- content model is %head.misc; combined with a single
     title and an optional base element in any order -->

<!ELEMENT head (%head.misc;,
     ((title, %head.misc;, (base, %head.misc;)?) |
      (base, %head.misc;, (title, %head.misc;))))>

notice that <noscript> is not defined whereas <script> is.