html5 elements and surrogate div
This article was first published on css-101.org (03-18-2011).
The proposed markup looks like this:
<article> <div class="article"> ... </div> </article>
Authors would nest a div inside new HTML elements (i.e.
aside etc.), and it is that
div that would be styled via class and/or id.
To be honest, that is what I thought the first time I heard about this idea. I wondered why one would want to implement something like that. Why not go the CC route then? At least, using Conditional Comments, we could avoid a wrapping that reminded me of the Twice-Cooked Method.
document.createElement does not do the trick. In short, there are other browsers than IE which we should consider.
Okay, I like the idea behind this, but I’m not sold on its value versus sticking with plain old ‘semantic’ HTML (POSH). What’s wrong with “old” HTML + WAI-ARIA (which would convey the same semantics to screen-reader users)? In other words, for whom should we be doing this and how much does this bring to the table?
I don’t have the answer to these questions and I hope people will join the discussion to enlighten me. But what I do know is the issues this technique raises. Because the lack of support for these new elements across browsers does not make this wrapping as insignificant as one might think.
A different DOM structure across browsers means queries relying on properties like:
will not be reliable.
With a different DOM structure, combinators (i.e.
~) and pseudo-classes like:
will fail each time the new elements are “in the way”.
In addition to which, such wrapping will put in play the default styling of these new elements (
display:block) which is is a deal breaker for some declarations on their “surrogate” DIVs (i.e.
display:inline-block). See “Nesting versus Wrapping”.
Another problem is the fact that authors won’t be able to style the new elements to prevent issues like these. This is because there is no hook and no other means to get to them.
It is the last issue above that made me think of using a different approach. If we cannot access the new elements via CSS it is because there is no such thing as a parent selector, but! If we were nesting the elements rather than using them as wrappers, then we could use the child combinator to get to them.
And as it turns out, this nesting seems to solve quite a few problems. Not only does it allow authors to reach the new elements (if ever needed), but it also fixes the
display issues I mentioned earlier and brings some CSS selectors back into the picture. See Nesting versus Wrapping for basic examples.
Nesting new HTML elements makes this new solution more consistent too as we would treat all elements the same, which is not the case with the wrapping technique as some elements cannot contain a
div. For example,
hgoup can only contain headings. An issue Tantek Çelik addresses in his book, in which he recommends to make an exception for such element, nesting
hgroup inside a
div instead of wrapping it with a
I’m not sure… Even if the nesting technique seems to solve a few problems, we’re still littering our documents with “junk” markup (yes, if it is used for presentation then it is junk). Some people justify this approach saying that once IE8 is dead, the clean up will be as simple as moving all attributes and their values from the
div to its “HTML5” parent (leaving out the class name that matches the new element). The suggestion being to replace in the styles sheets the said class name with the element name. For example, going from:
Which is very dangerous as
type are selectors of different specificity (
0,0,1). In my opinion, a much safer approach would be to leave the class names alone. This would create some redundancy (i.e.
<section class="section">), but will not mess with the cascade. Still, we would encounter problems if CSS rules contained any reference to new elements (as the nesting technique would permit).
What about writing clean markup and delivering elements depending on user agents? For example, we’d write markup like this:
<aside class="aside"></aside>, etc. but then we’d swap all these elements with
divs depending on which UA makes the request. I know, browser sniffing is a bad idea (as this would not be based on the browser ability to deal with HTML5 elements), but what else can we do to move forward without polluting our documents with non semantic wrappers?