Assuming that it’ll be a while before most browsers attempt to implement most of HTML 5 (a perfectly reasonable assumption) we need to start thinking of ways to tackle the creation and rendering of HTML 5 components in the meantime. Obviously, using the tools of JavaScript and CSS we can accomplish a lot.
However, there is one notch in our weapon: Internet Explorer doesn’t know how to render CSS on elements that it doesn’t recognize. For example, the following “blah” element (a fictional element) doesn’t have any styling:
<html> <head> <style>blah { color: red; }</style> </head> <body> <blah>Hello!</blah> </body> </html>
Result:
Thankfully, Sjoerd Visscher mentioned an interesting technique that could be used to force IE to use the specified CSS styling. Specifically, once you create a new DOM element (of the same name as the one in the document) all styling is applied. You don’t even have to inject the element in order for this to occur. Observe the following:
<html> <head> <style>blah { color: red; }</style> <script>document.createElement("blah")</script> </head> <body> <blah>Hello!</blah> </body> </html>
Result:
This is very important. This now means that we can provide CSS styling for undefined HTML 5 element and allow Internet Explorer to handle it gracefully.
<figure/> element
Let’s take a look at a simple example. Pretending that we wanted to set about implementing the HTML 5 figure element. The element is quite simple, only requiring some basic CSS markup (I’m not completely sure how a figure is supposed to look so I took some liberties here).
<html> <head> <style> figure { border: 1px inset #AAA; padding: 4px; } </style> <script>document.createElement("figure");</script> </head> <body> <figure> <img src="https://johnresig.com/files/jeresig-wordpress-sm.jpg"/> </figure> </body> </html>
Result:
Using some basic CSS, and a single JavaScript DOM statement, we’ve now implemented at least part of the HTML 5 spec. While it won’t solve everything, it is a promising technique, at the very least.
I did have some issues when I was testing this technique, especially with the styling of elements that are already defined elsewhere in the structure. For example, let’s say you wanted to implement the legend child element of a caption. This ends up being really hard since the functionality and styling of legends are already defined for fieldsets by Internet Explorer. In my simple tests they became unstylable outside the context of a fieldset.
This is definitely a decent start, building our HTML 5 shiv, but it needs some more work and much more exploration. I hope to see this continued in the upcoming months as interest in, and availability of, HTML 5 begins to heat up.
Andrew Dupont (January 24, 2008 at 3:33 am)
God, it’s like IE was designed by a mischievous wizard — awful, but with nuggets of hackability that seem unintentional but, when taken together, imply a grand design behind it all.
Or it could just be serendipity.
Jacob Rus (January 24, 2008 at 3:50 am)
John, do you know how this sort of thing can be accomplished in any/all the other browsers? I seem to remember that one or more of Webkit and Gecko also have trouble styling unknown elements (and I have no clue about Opera, iCab, etc.). I’ve been interested in trying to use HTML5’s new structural elements in my own pages, but at the moment it seems like they need to be wrapped in div’s or similar to be styled correctly.
This would actually be a great topic for some official WHATWG page—how to use new HTML5 elements in as many old browsers as possible, what workarounds are needed to get things to be properly styled in each—as part of a larger document about best practices for making websites as compatible as possible both with HTML 5 and with current browsers.
And maybe this blog post (and potentially such a longer resource) should be linked to from here?
Dean Edwards (January 24, 2008 at 3:58 am)
https://sourceforge.net/projects/wf2/
And isn’t it a “shim” rather than a “shiv”. What’s a shiv?
Jacob Rus (January 24, 2008 at 4:06 am)
One more comment, though this may be straying slightly off-topic. Along similar lines, I’d like to sometime in the nearish future, hack together some javascript to make a wrapper of XHR which supports the new server-sent events format (see here), at least in Firefox/Safari. I think IE support would still depend on using Flash/Java/Silverlight/something instead of just XHR, or else on servers sending a differently formatted event stream to IE and older versions of other browsers.
Along with things like the IECanvas stuff, all of Dean Edwards’s various scripts, etc. it would be nice to see some larget project aimed at finding out to what extent it is possible for various JavaScript shims (I think you meant “shim†not “shiv†btw) to make all browsers support HTML5-compliant—and JS, CSS3, DOM, etc.—sites, and see how far back, in terms of browser versions, such support can be pushed.
Dean: “shiv†is a slang term for switchblade. :)
kL (January 24, 2008 at 4:58 am)
Now only Firefox is left!
Opera and Safari handle it well already.
jgraham (January 24, 2008 at 5:10 am)
Jacob: Webkit and Opera have no difficulty processing unknown elements. Gecko has no difficulty if the element contains HTML-inline content but doesn’t work correctly for elements containing HTML-block content (effectively all unknown elements are treated as inline). This makes new tags like <section> and <figure> impossible to use in gecko :( (see b.m.o bug 311366 for more details; standard disclaimers about using bugzilla responsibly apply).
John: It has been suggested that something other than <legend> be used in <figure> because of the backward compatibility issues with legend.
Flavio (January 24, 2008 at 5:39 am)
Why the Web has to be such a pile of hacks? Can’t you wait until the IE team officially onnounce HTML5 support, if they ever will?
Can’t we stop this hack-me-before-I-hack-you development strategy?
Jacob Rus (January 24, 2008 at 7:03 am)
And there’s no way whatsoever to hack that into Firefox 2 with some clever JavaScript?
Toe (January 24, 2008 at 8:08 am)
Jacob Rus (et al.): ‘shiv’ as I’ve known it refers to any homemade knife, especially as a prison weapon.
That said, I thought Chris Wilson’s use of it in reply to John’s post yesterday (Meta Madness) was interesting:
“I want to jam standards support into (this and future versions of) Internet Explorer. If a shiv is the only pragmatic tool I can use to do so, shouldn’t I be using it?”
Quite an interesting metaphor, isn’t it? ;)
Sean Hogan (January 24, 2008 at 8:14 am)
@dean: shiv seems as appropriate as shim
@jgraham: I tested creating the content in Javascript long-hand and that seems to allow HTML block content. (both IE and Firefox)
My script as follows:
window.onload = function() {
var figure = document.createElement("figure");
var legend = document.createElement("legend");
legend.appendChild(document.createTextNode("Image"));
figure.appendChild(legend);
var img = document.createElement("img");
img.src = "http://ejohn.org/files/jeresig-wordpress-sm.jpg";
figure.appendChild(img);
var span = document.createElement("span");
span.appendChild(document.createTextNode("Note"));
figure.appendChild(span);
document.body.appendChild(figure);
}
jgraham (January 24, 2008 at 9:39 am)
Sean: Sure, if you bypass the HTML parser then the Gecko DOM code will allow unknown elements with any children. The problem is that the parser code thinks that all unknown elements are inline and that inline elements shouldn’t contain blocks, so it closes the unkown element as soon as it encounters a block level child. Simply fixing the parser code to allow unknown elements to be either block or inline doesn’t seem to be sufficient because it breaks the handling of misnested formatting elements, which potentially breaks the web.
There are a few ways around this; you can enclose all children of unknown elements in <span> tags, which has the effect of making your pages totally invalid. You could do some crazy javascript fixup using the unknown element start tag (which is in the DOM) to identify the start of the children of the unknown element and a magic comment to identify the end of the children. However neither of these are nearly as good as the problem being properly fixed :)
J. Pablo Fernández (January 24, 2008 at 10:21 am)
Is working in this way in Firefox really worth it? Doesn’t it make sense to just go and hack on Firefox’s source code so the next version contains HTML5 support. That’s likely to happen anyway, in some time.
Super Mike (January 24, 2008 at 10:52 am)
I thought HTML5 was neat, but now that the rush is on to switch from HTML 4.01 Transitional to XHTML Transitional, I think the door is closed for HTML5 and it’s a moot issue. I mean, 2008 is the year when everything goes XHTML and even this page you’re reading now is in XHTML. At best all we can do is encourage the W3C to improve the next version of XHTML with HTML5-like features. As well, I’m putting in my vote for Ogg video and audio playback, and features so that we don’t have to do so much Javascript.
Karl Swedberg (January 24, 2008 at 11:08 am)
@Super Mike: Who is rushing to XHTML transitional? I’ve been seeing something entirely different: a slow crawl among web-standards-aware developers away from XHTML transitional to HTML 4.01 strict. This page is in XHTML because that has been the default for WordPress installations. From my perspective, HTML is growing, and XHTML is moribund.
Adam (January 24, 2008 at 11:43 am)
@Super Mike
Two things that you need to be aware of.
First, HTML5 is sometimes known as (X)HTML5 because it specifies two concrete syntaxes for HTML5, HTML and XML. That is to say, that there is that if there is a race to XHTML then that race can be to the XML syntax of HTML5.
Second, to make things totally confusing, the W3C also has an XHTML2 Working group. This has lead to some debate as to whether the HTML5 WG should refer to the XML syntax as “XHTML” to avoid confusion and hard feelings.
Third, there has been some discussion on the WG as to whether or not we need an XML syntax. Those who think its unnecessary seem to suggest (to me at least) that there is no compelling reason to rush to XHTML given all the myriad browser issues associated with it right now.
So, I would suggest that your opinion is not based on the facts (except for the Ogg bit, I’d like to see it to but there are significant issues that need resolving).
How do I know this? I’m an Invited Expert for the HTML WG.
Matthew Babbs (January 24, 2008 at 2:06 pm)
As Sam Ruby pointed out over on annevankesteren.nl, Firefox has no problem with unknown block level elements if you use HTML5’s XML syntax and an XML MIME-type. The effort required to make that actually work may be too much for many people, but at least it’s there for the determined.
-TNO- (January 24, 2008 at 2:09 pm)
Should we expect to see a resurgence of HTML Components for IE?
http://webfx.eae.net/dhtml/blink/blink.html
Fredrik W (January 26, 2008 at 4:11 am)
I might have bad eyes and missing it somehow, but does it work with nested selectors as well?
el.classname, el el, #id el etc?
Bhasker V Kode (January 26, 2008 at 8:21 am)
hey john,
i’ve even played around with event handling with undefined html element in the returnable project.
While adding events to these nodes (in my case ) worked as expected in firefox,opera , but in ie exposed only different quirks which needed you to dynamically add a child into the custom node,and then add handlers .
nice to see visscher’s interesting technique for css as well 8 )
Keep Clicking,
Bhasker V Kode
Andrei (January 28, 2008 at 6:20 am)
I think the most interesting bit that everyone seems to be missing is “how many web developers do you think are going to jump on the HTML5 DTD?”
Plausible answer? Depends on browser support.
If Gecko/Webkit/Opera support it upon release (which is likely, given their track record), the priority to shift would be placed on the “take note” board. Once IE implements it, THEN everyone will jump on it.
But for the near future? It makes zero sense to write JS code for a single element that can be given a current HTML/XHTML tag and an ID or class, only to write more JS code, to tweak/implement the other JS HTML5 hack code, for the browser DOM.
I mean geez… just so you can say “Valid HTML5” on the footer?
Making a website that works cross-browser/cross-platform and follows accessibility standards should always be first priority. What version of HTML/XHTML was used to achieve this never matters.
Robert O'Rourke (January 28, 2008 at 7:53 am)
Hi John, I thought this might be worth mentioning because this post reminded me of it:
http://dean.edwards.name/my/abbr-cadabra.html
I guess it doesn’t make a difference (besides the use of JS) but may be interesting to try out in terms of how this method affects the DOM/events etc…