(Un)Target with style and XML

Published 2012-02-01 19:19 by Leif Halvard Silli

This page is about how one could take advantage of the differences betwen HTML and XML parsers in order to make e.g. an style element take effect in a HTML parser, but not in an XML parser — and vice versa. That is: Send the same code, but get a result that depens on the parser kind.

First – let’s go XML-uncompatible
<!--[if !IE]><!--><style>/*<!--<![endif]-->
<style  type="text/html" >/**/
    p{color:red;}
</style>

The above works as HTML, but is not XML-compatible, due to the second — unclosed — start tag:

<style  type="text/html">
Why does it work (in HTML) ?

Because the following works — it is even conforming, per HTML5, to do so:

<style>/*<style>*/body{background:red}</style>

The second start tag is simply ignored: The only tag the HTML parser looks for is the closing tag — </style>. Several HTML tags — such as iframe, object, style, script. — work same way. Thus, also for the script tag, one could do the same thing this:

<script>/*<script>*/javascript code here</script>
Now, lets go XML-compatible
<!--[if !IE]><!--><style>/*<!--<![endif]-->
<style  type="text/html" />/**/
    p{color:red;}
</style>

The above is XML-compatible, because the second start tag is self-closed:
<style type="text/html" />
(Self-closed tags are not considered self-closing by HTML parsers — so this plays no role to them.) But note that allthough it is XML-compatible and thus works in both HTML and XML, it isn’t considered polytglot. This is due to the fact that XML parsers see two style elements — one inside another — whereas HTML parser see the second tag as simply plain text. See the comments section below.

Non-conforming untargeting of HTML parsers
<style type="text/html" />
<style type="text/css" >
    p{color:red;}
</style>

The above style elements will work in XML parsers — which will see two style elements: One that is self-closed, and one that is not self closed. HTML parsers, however, do not recognize the self-closing syntax and thus, to them, the above is just a single stylesheet, which they will ignore.

Per HTML5, the above is however non-conforming. But per XHTML 1.x, then there are no restrictions — the above is valid. (The HTML5 rules probably makes more sense, but it may come in handy to know that it nevertheless is valid per XHTML 1.x.)

Non-conforming untargeting of XML parsers
<style type="text/css" />
<!--/*--><style type="text/html" >*/
    p{color:red;}
</style>

Here, because the HTML parser doesn’t understand the self-closing syntax, it will think that the style element lasts until it sees the HTML-compatible end tag— </style>. Whereas the XML parser will consider that the first start tag is autoclosed — and it will also not consider the second element to contain a valid style sheet.

Again, this is non-conforming per HTML5. But it would be conforming XHTML5 and also conforming XHTML1.x. And it works.

XML-compatibility, polyglotness etc

In my recent postings, I made a point of saying that untarget with style and target with style are XML-compatible. What did I mean by that? Two things: Firstly, that the method is well-formed — if you do it correctly. Secondly, that the method is polyglot — it results in an identical DOM in XML and in HTML. It is only in the current — soon to be legacy — versions of Internet Explorer, that the DOM will differ. The rest — the world of conforming XML and HTML parsers — see the same DOM.

Now, the primary end result goal of HTML-compatible — polyglot — markup — is identical DOMs. However even the polyglot mark-up spec make some exceptions for XML specific attributes. Why not make some more exceptions, as we see fit? And so, if we look away from the constraints of the Polyglot Markup specification, then we can extend our CSS hacks: We can create pages that for all normal purposes are polyglot, even if they do not — to the letter — conform to the polyglot markup rules. We can even create page where the CSS works in XML parsers but not in


|