Grow your CSS skills. Land your dream job.

Fix Inserted HTML5 Content with HTML5 innerShiv

Published by Chris Coyier

When working with HTML5 today, many of you know that you'll need to include the "HTML5 shiv" to ensure that CSS will recognize and be able to style those elements in browsers that aren't yet hip to HTML5.

<!--[if IE]>
  <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->

Credit for that to Remy Sharp, Jon Neal, John Resig and anybody else who contributed to that idea. Also for the benefit of those non-hip browsers, it's best to reset many of the HTML5 elements to block-level as they should be:

article, aside, figure, footer, header, hgroup,
menu, nav, section { display: block; }

Now we're all set to use and style HTML5 elements. But wait! What happens if we dynamically add HTML5 to the page via JavaScript.

var s = document.createElement('div');
s.innerHTML = "<section>Hi!</section>";
document.body.appendChild(s);

Or in jQuery:

$("body").append("<section>Hi!</section>");

Hip browsers do fine, but Internet Explorer will once again not recognize the new element and not apply CSS to it.

Joe Bartlett has written a great work-around to the problem called HTML5 innerShiv and I thought more people should be aware of it.

Update January 2013: This is now included in the canonical html5shiv project, you should use that. The rest of this project is a bit outdated. You don't need to do it this way anymore if you use the html5shiv.

Using it

Please note that this script does not require jQuery. It's just vanilla JavaScript and will work with any library or library at all.

1. Download

Download the script and insert it onto your page. Or copy and paste the script into other JavaScript you are already loading if you want to avoid an extra HTTP Request.

2. Wrap all HTML content in innerShiv function before inserting

Here is the same jQuery example as above, made to work using innerShiv:

$("body").append(innerShiv("<section>Hi!</section>"));

Quick demo.

Comments

  1. Permalink to comment#

    Slightly unrelated, but I’ve been wondering this for some time and perhaps someone here will have an answer. (And this is not solely in the interest of graceful degradation; I have clients who use IE 6-7 and are sometimes forced to disable javascript.)

    Can the whole html5 shiv-thing be done without relying on javascript? Could IE’s native behaviors (.htc) be used to force recognition?

    • Great question, I’m not sure but it would be worth finding out.

    • I believe .htc’s still requires JavaScript to be enabled.

    • Permalink to comment#

      I can’t seem to find a straight answer on that. I know HTCs make use of javascript and VBscript (some articles on microsoft.com(see the note under bullet #2) seem to imply you can run binaries), but I can’t tell if it’s all turned off when javascript is or not.

    • Permalink to comment#

      If they have Javascript disabled then the shiv wouldn’t be needed since no HTML5 elements can be added via Javascript. (This is assuming I correctly understand what this script’s purpose is)

    • Permalink to comment#

      I’m actually referring to the problem of using html5 elements/attributes in general, not necessarily adding them through javascript (hence the “slightly unrelated”-ness of my original comment).

      You’re right about the innerShiv that Chris is describing in this article, of course.

  2. Permalink to comment#

    cross browser problem has always troublesome

  3. Yes! I ran into this exact problem six months ago and had to abandon parts of an HTML5 project because of this. I’ll have to try to go back and see if IE will play nicely with innerShiv.

    Thanks for the tip!

  4. I like the idea but my problem is that I have some jquery pluggins that need the innerShiv. I feel this needs to be implemented at a higher level so that all this javascript doesn’t have to be rewritten.

    • It’s small enough that you could just chuck it into your jQuery plugin without much issue. Although that’s an interesting idea, I wonder if jQuery (or other libraries) would consider incorporating this idea into core.

    • Take a look at Jaxer’s implementation of Server Side JavaScript. If you run HTML Shiv server-side then the normal client-side JS issues vanish and there’s not special IE stuff going on

    • There are some occasions when you might not want to apply innerShiv to your HTML (for example, if the HTML is a table fragment–see the github project’s issues page for more info on this). So be careful about weaving it into generalized plugins and libraries.

  5. er
    Permalink to comment#

    couldnt this guy just send his contribution to html5shiv people? one already established html5 utility js sounds better than inserting that hack by hack to every page…

    • This idea has a bit of a different scope than the HTML shiv. This is needed only when inserting content dynamically onto the page, not for every single page that uses HTML5 elements. The super similar name though I agree is a bit confusing.

  6. nice fix; duly noted

  7. Permalink to comment#

    The issue this fixes was keeping me from using the new HTML5 elements. Thanks for the heads up

    This should be worked into jQuery core so you can continue to use .append() without worrying about .innershiv() at all…

  8. bobby
    Permalink to comment#

    why write in html5 if its not yet supported in many of the browsers? what’s wrong with xHTML ?! is the same shit… I know many of you do because, they think it’s cool and nice. Adding 100 js to make it work it’s not cool!

    • Jason
      Permalink to comment#

      The main drawback is ie6

      ie6 is almost 10 years old

      maybe you should ask yourself why you are dragging your knuckles and not embracing change?

      HTML5 tags make your markup cleaner and meaner!

      not not cool !!!! :)

    • Tomas
      Permalink to comment#

      I agree with Bobby. People are so quick to dig into something new and cool and later discover all problems. HTML5 is the new buzzword and the trendy coders need to be up to date and talk about it. Markup cleaner? The enduser doesn’t care. Google doesn’t care, it prioriates value. At the moment you can’t do anything new that work crossbrowser in HTML5 that you can’t do in older HTML/Flash. Smart people wait til it come anything useful to use it for, this isn’t rocket science to learn.

  9. Chris,
    Thanks for your continued hard work. CSS-tricks is always top of my list to check out every day. I understand the virtue of wanting html 5 to work earlier than browser adoption allows, but I wonder if Javascript is the way to go here?

    The point of tags like “section” is to increase the semantic range of html, not necessarily to “do” something (ie where the div tag could work fine). If Javascript is the inserting agent into the markup then search engine robots won’t see it, and it actually won’t help your website be more expressive or meaningful in anyway.

    I’m excited to let search engines see more expressive, and semantic mark up in my designs, but it seems that a server-side solution is the only way to do this know, and still maintain cross-browser support.

    Keep up the good work!

    • Tomas
      Permalink to comment#

      Regarding all talk about semantics. Who is it for? In the long run it’s good that net got better structure. But what would a search engine do about it? I think nobody knows yet. It would be stupid for Google to rank html5 sites better than old. A good site is a good site, it shouldn’t analyze the details that enduser doesn’t care about. If it come a good purpose, wouldn’t it be easier to check then how much work to apply instead of put more work now?

  10. hwany
    Permalink to comment#

    Hmm…is there any way to do this on innerHTML, specifically jQuery.load()?

  11. Sorry if this sounds a like a stupid question but will you still need to use the normal HTML5Shiv as well as this one?

  12. Adriano
    Permalink to comment#

    IE9 should have better or full support of HTML5 elements. Should the conditional comments be:

  13. Adriano
    Permalink to comment#

    if lt IE9

    • Permalink to comment#

      @Adriano: If you write a conditional statement of if lt IE9, that translates to “if less than IE9″. However, if you want to write a conditional statement for IE9, you could write “if IE9″, OR, you could also wrote “if lte IE9″, which translates to ‘if less than or equal to’.

      IE9 will conditionally accept both, but with different circumstances

  14. Ray
    Permalink to comment#

    Nice, thanks for sharing

  15. I think Html5 is very cool and will become fashionable very soon .While some old edition of IE6 Web browser will surely be out !

  16. Permalink to comment#

    thanks nice topic

  17. nice one chris

  18. Nick
    Permalink to comment#

    Is is just me that finds the usage of ‘shiv’ simultaneously confusing and amusing. AFAIK ‘shiv’ was a typo, and the intention was for the much more appropriate word shim.

    Not that it makes a difference, and I do somewhat like the idea of having to threaten IE with a code shiv in order for it to do my bidding.

    FYI: http://html5shim.googlecode.com/

    • I’m pretty sure you are right. Shim is 10x more appropriate. But I think it’s too late now and it’s kinda funny.

  19. Sweet! I came up against this exact problem the other day and despaired because it stopped me doing what I wanted to do with the proper HTML5 elements. Now I can do what I actually wanted – great stuff!

  20. if you’re already using HTML5 most likely you’ll also be using Modernizr. this kind of functionality is already included in Modernizr, so no need for a separate library.

  21. suprsidr
    Permalink to comment#

    Holy super-smart Batman!
    html5boilerplate

    -s

  22. Jayne Walsh
    Permalink to comment#

    Hi , I am building my first website and have been using HTML5, however my client uses IE and so site must be compatible. Theres no clever tricks just smooth scrolling nav bar and have used sections rather than divs. Have included the shiv (mentioned above) in the head. Using a mac so not been able to test in IE. If there is a problem should I just change the sections to divs do you think?

  23. Permalink to comment#

    Since IE9 supports html 5, can I also use <!--[if lt IE 9]> instead of <!--[if IE]>, or is this a bad idea?

    • Permalink to comment#

      ps. It seems that the update of this post about the html5 innershiv has been updated:

      Quote: “STOP! Don’t use innerShiv! html5shiv now patches for the innerHTML issue! Update html5shiv and you won’t have to use innerShiv anymore.”

  24. Mark

    Not sure why, but that shim seems to confuse win81-64 dw and mew previews, maybe doing that gastly FP hidden code thing… using IE11 you get everything but a few transforms. Desktop unfiltered html5 with this thing for the published site… maybe. Oh, but Sublime has no problem and dw is getting better.

    !--[if IE]
    script src="http://html5shiv.googlecode.com/svn/trunk/html5.js" /script
    ![endif]--
    
This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".