Same Markup: Using

,

, and

On this blog we’ve repeatedly discussed enabling the "Same Markup" for Internet Explorer 9. Part of making "Same Markup" a reality involves supporting the right features in IE9 to make the same HTML, JavaScript, and CSS "just work" the same way they do in other browsers. Part of how IE9 contributes to enabling the "Same Markup" is through support for the <canvas>, <audio>, and <video> elements from HTML5. These were introduced in the third platform preview and continue to be improved with each update.

In my first post on "Same Markup", I described the effort as an "n-way street". Each browser has a part to play by supporting the right features with the right behavior. Web developers also have a part to play in how they code for cross-browser differences where they unfortunately still exist. The most important part of working across browsers for web developers is to detect features, not browsers. So in this post I'll outline how to use feature detection for <canvas>, <audio>, and <video>.

Detecting Support from HTML Markup

Unlike other features, support for <canvas>, <audio>, and <video> can be detected directly from HTML markup. This involves simply using the desired element, then placing fallback content inside of it intended for browsers that don't have support for these elements. Browsers with support will hide this content from the user and display only the <canvas>, <audio>, or <video> element itself.

 <!-- Example 1:  Basic <canvas> fallback -->
<canvas>
    This text only displays in browsers without canvas support.
</canvas>
 <!-- Example 2:  Basic <audio> fallback -->
<audio>
    This text only displays in browsers without audio support.
</audio>
 <!-- Example 3:  Basic <video> fallback -->
<video>
    This text only displays in browsers without video support.
</video>

One caveat to keep in mind is that fallback content is only hidden visually. <script> blocks and other items in fallback content will always execute, even in browsers that support these elements.

 <!-- Example 4:  <script> always executes in fallback content -->
<canvas>
    <script>
        alert("This always runs, even when canvas is supported.");
    </script>
</canvas>

Of course, fallback content should also be useful. Exactly what qualifies as useful can vary depending on what you are trying to do. One approach is to point the user at a download for an upgrade, but in most cases it is a better experience for consumers to fall back to alternative approaches for delivering the content. For example, if you're drawing something that doesn't change much to a canvas, you may be able to fall back to an image that gets generated server-side. A better alternative could involve including a framework which implements canvas on top of existing web technologies or using a widely deployed plug-in.

The <audio> and <video> elements tend to have more options for fallback via plug-ins, whether through a media player or an app built on top of a widely deployed technology such as Flash or Silverlight. At the very least you can provide the user with a link to download the file so they can play it locally. The examples below provide a rough view of this type of fallback, though the <object> tag generally requires a number of varying parameters specific to the chosen plug-in.

 <!-- Example 5:  Provide useful fallback content for <audio> -->
<audio src="myaudio">
    <object type="audio-plugin-mime-type" data="myaudio">
        <a href="myaudio">Download the audio file</a>
    </object>
</audio>
 <!-- Example 6:  Provide useful fallback content for <video> -->
<video src="myvideo">
    <object type="video-plugin-mime-type" data="myvideo">
        <a href="myvideo">Download the video file</a>
    </object>
</video>

Detecting Support from Script

In addition to HTML markup, support for <canvas>, <audio>, and <video> can also be detected from script. This detection can be performed many ways, but one of the simplest is to check for the existence of the appropriate interface object off of window.

 // Example 7:  Simple feature detection for <canvas>
if(window.HTMLCanvasElement) {
    // Code requiring canvas support
}
 // Example 8:  Simple feature detection for <audio>
if(window.HTMLAudioElement) {
    // Code requiring audio support
}
 // Example 9:  Simple feature detection for <video>
if(window.HTMLVideoElement) {
    // Code requiring video support
}

An alternative approach for detecting <audio> and <video> involves checking for the existence of the canPlayType method on a dynamically created <audio> or <video> element. This is used by a number of frameworks and is generally preferred if you also intend to use the canPlayType method to test for supported codecs (which will be covered in a future post). If you simply need to test whether <audio> or <video> is supported, then I find the approach outlined above in examples 8 and 9 to be more obvious and equally as effective.

 // Example 10:  Alternate feature detection for <audio>
if(document.createElement("audio").canPlayType) {
    // Code requiring audio support
}
 // Example 11:  Alternate feature detection for <video>
if(document.createElement("video").canPlayType) {
    // Code requiring video support
}

A similar alternative approach can be used for detecting <canvas> support. In this case, most frameworks have settled on checking for the existence of the getContext method. This makes sense for <canvas> given that this method is required in order to retrieve a context for rendering. In order to avoid false positives in a couple of mobile browsers, an additional check confirming that a context can actually be retrieved is needed as well (thanks to Paul Irish for pointing this out).

 // Example 12:  Alternate feature detection for <canvas>
var canvas = document.createElement("canvas");
if(canvas.getContext && canvas.getContext("2d")) {
    // Code requiring canvas support
}

Next Steps

If you have previously used browser detection to decide whether to use <canvas>, <audio>, or <video>, now is the time to update to use feature detection instead. Also, make sure you have a DOCTYPE at the top of your page (e.g. <!DOCTYPE html>) so your content doesn't render in Quirks Mode. In IE9, Quirks Mode is used for compatibility and consequently the <canvas>, <audio>, and <video> elements will not work there.

Stay tuned for future posts covering how to detect supported codecs and specify multiple sources using the <audio> and <video> elements.

Tony Ross

Program Manager

Edit 9/3 - added link to earlier blog post in second paragraph

Edit 9/9 – Edited Example 12 based on feedback from Paul Irish.

Comments

  • Anonymous
    September 03, 2010
    Good blog. Blue-on-blue hurts my eyes though :(

  • Anonymous
    September 03, 2010
    use <audio> markup,how to get the ID3 info of mp3.

  • Anonymous
    September 03, 2010
    I find it ironic that the title of a post about interoperability does not render correctly in Google Reader's feed. It renders as Same Markup: Using , from Internet Explorer Team Blog by ieblog The tags are missing.

  • Anonymous
    September 03, 2010
    I find it ironic that the title of a post about interoperability does not render correctly in Google Reader's feed. It renders as


Same Markup: Using , from Internet Explorer Team Blog by ieblog

The tags are missing.

  • Anonymous
    September 03, 2010
    This is great! I can't wait to use it! Will innerHTML also be fixed in IE9? It is still currently broken in all versions of IE up to IE9 preview 4.

  • Anonymous
    September 04, 2010
    to vaibhav, why do you find it "ironic" that Google Reader is too dumb to properly render text?  Google Reader is not a web browser. to ashelysu, it does not appear that the HTML5 audio tag has a mechanism to expose metadata from the ID3 tag to the DOM.

  • Anonymous
    September 04, 2010
    I've seen this referred to as fallback or alternative content, I think it's WAI related offhand? I really like the choice to NOT support these elements in quirks mode.

  • Anonymous
    September 05, 2010
    Regarding the comment feeds, would it be possible when a blog entry stops accepting new comments, that the feed version of the comments includes a final entry stating that no more comments are being accepted, so people like me who use feed readers to keep up with the comments know when to unsubscribed? Thanks!

  • Anonymous
    September 05, 2010
    Reminder: HTML5 Forms, CSS3 Transitions, Gradients, Text Shadow, Multi-Column, and more.

  • Anonymous
    September 05, 2010
    <embed/> support detection is needed for SVG support. if (win.HTMLEmbedElement) seems to work fine though. Detecting Native v Adobe SVG support in <IE9            try {                if (document.implementation.hasFeature("www.w3.org/.../feature, "1.1")) {                    // display SVG                    //document.getElementById('svgViewbox').style.display = 'block';                }                else {                    // Test for Adobe SVG Plugin                    try{                    var oSVG = new ActiveXObject('Adobe.SVGctl');}                    catch(e)                    {                        document.getElementById('divNoSVG').style.display = 'block';                    }                }            }            catch (e) {                // Test for Adobe SVG Plugin                try {                    var oSVG = new ActiveXObject('Adobe.SVGctl');                }                catch (e) {                    document.getElementById('divNoSVG').style.display = 'block';                }            }        }       //window.onload = SVG_Init; However there seems to be some issues using master pages and content pages in VS.... I will post at connect.

  • Anonymous
    September 05, 2010
    @Vaibhav Garg: If you check the XML feed, it properly escapes the tags by using entities - and it's valid XML. It's the Google Reader that's processing it wrong.

  • Anonymous
    September 05, 2010
    I was rather abruptly downvoted for suggesting a method similar to the script support detection method for <canvas> over on Stack Overflow a while ago - stackoverflow.com/.../2745459.  My answer there was accepted, then unaccepted after a couple of downvotes, so reading this post made me feel a little better about it :-)

  • Anonymous
    September 06, 2010
    Please fix innerHTML! Is canvas supported yet? I've visited some html5 sites and IE doesn't show anything!

  • Anonymous
    September 06, 2010
    @exy: CANVAS is supported in current IE9 Platform Preview builds. If you find CANVAS sites that don't work with IE9, please post bugs at Connect or share the URLs here.  thanks!

  • Anonymous
    September 06, 2010
    @exy you can retrieve the innerHTML of <canvas> and inline <svg> with        if (doc.selection.type == 'None') {            selectedHtml = fixTags(el.outerHTML);        } IE9 PP has corrected unquoted attribute values, but tag names are still returned in uppercase... hence the fixTags function above... The W3 validators don't complain now with unquoted attribute values if the current documentMode==9 and you are using a code snippet retrieved from the innerHTML of a selected tag. I expect that <canvas> and other new HTML 5 tags will return a different selection.type value once the iexplore.exe GUI is added and the context menu handlers for the new tags are updated. Currently abbr, acronym, center, cite, code, command, del, defn, canvas and svg tag names return a selection.type of 'None' I would not be using document.write(el.outerHTML); or NewEl.innerHTML=el.outerHTML though, so the above workaround only applies to context menu utilities like Copy HTML that you may be using to inspect the contents of AJAX responses injecting markup into a page. of coarse You can always use the Script tab of the Developer Tools to copy the innerHTML of any tag, except injected markup from document.writes or innerHTML assignments.

  • Anonymous
    September 06, 2010
    The comment has been removed

  • Anonymous
    September 06, 2010
    After reading more discussions on the slow tab loading I decided to investigate using the only tool that matters in the windows world - procmon! I opened IE, started logging, and then opened a total of 20 blank tabs (not the new tab page, just a blank tab) then stopped logging... here's what I found For 20 blank tabs in IE8: 1072 files created! 315 images loaded! 306 files locked! 760 file reads of a single file! "shdocvw.dll" - are you serious? 257 registry keys created! 27,105 registry keys opened! 23,463 registry keys queried 600 registry values set 715 file writes not to mention all the threads created, files and registry keys closed, etc. 27,000+ registry keys?!?!?! oh my gosh! what on earth is that all being done for? NO WONDER IE8 tab opening is so slow!

  • Anonymous
    September 06, 2010
    Good info.. I am linking some stuff on this blog in my blog...for non-techie users

  • Anonymous
    September 06, 2010
    The comment has been removed

  • Anonymous
    September 06, 2010
    The comment has been removed

  • Anonymous
    September 06, 2010
    @ Give it up Klimax If your IE8 new tab openings are longer than about 0.2 or 0.3 seconds there is something irregular with your IE8 installation. Likely caused by plugins or addons or by your security software. I just today installed a fresh W7 on a clean empty PC again and tab opening is quick and stays quick troughout its use.

  • Anonymous
    September 06, 2010
    I don't like to troll again but users can see through "your same markup" illusion. Only a monopolistic company like Microsoft can conveniently ignore the rest 60% of the XP world. Hardware acceleration isn't critical to the standards-compliant rendering that every Windows user should have long got. With even Vista Home/Ultimate support ending in 2012, IE9 is more like an Ultimate Extra for Windows 7.

  • Anonymous
    September 06, 2010
    Sigh, would it be possible to update the blogging software on this site to somehow add filters for user accounts? I am truly tired of seeing posts on here about innerHTML and support for Windows XP. I truly get why XP is not being supported, and I support that move by Microsoft, and comments on innerHTML just aren't appropriate here.

  • Anonymous
    September 06, 2010
    The comment has been removed

  • Anonymous
    September 07, 2010
    Neat!  You can plug almost anything else in this sentence and make it just as silly! <<Only a monopolistic company like Microsoft can conveniently ignore the rest 60% of the XP world>> Only a monopolistic company like Apple can conveniently ignore the 90% of the world using Windows. Only a monopolistic company like RedHat can conveniently ignore the 90% of the world using Windows.

  • Anonymous
    September 07, 2010
    @Klimax : have you heard anybody complaining Firefox or chrome slow tab open time? please dont say "yes".. it will be too biased. But there are many complains for slow tab in IE 8... see here: www.google.com/search or here www.bing.com/search Do I need to say anything else MS?

  • Anonymous
    September 07, 2010
    hims: There are plenty of complaints about slow Firefox due to add-ons. So many so that the Firefox team themselves blogged about it; there was a link to a post on that topic in the comments a few days ago. Same culprit: poorly-written addons.

  • Anonymous
    September 07, 2010
    The comment has been removed

  • Anonymous
    September 07, 2010
    The comment has been removed

  • Anonymous
    September 07, 2010
    hims: Heh,still selection bias - those who have no problems have no reason to talk. And how many of complainers have done tests and tried to understand what is going on. You seem to know some of them - link please(and not just generic "IE is slow") or run test yourself and report times.(along with specs of machine) Just for good measure: D510,1GB RAM,SSD HDD: 125ms for first new tab and 109ms for next. Startup time of IE8 is about 5s (large RZ) As for other browsers -those who have issue rarely complain too loud and just move to others. (Altough former FF users are quite a bit vocal about issues with FF)

  • Anonymous
    September 07, 2010
    The comment has been removed

  • Anonymous
    September 08, 2010
    Frank can't read. I used for the first measurment on fresh system (about dozen starts of Windows) stopwatches - huge error margins like 500ms(distribution around correct time is unkown);reaction time of human is not that good. That was why I dug up old Connect Ticket,so we had common method,which was repeatable.(the only time requiring stopwatches is startup of IE) And with that I published second set of )resutls from same machine. Not sure what changed (no updates or other installations nor changes to settings) but I got same times I got for other PCs. Don't know what caused those 3s(what is left after correction for error margin),but it is away. And Frank even ignored my comment that RZ is huge.(Accounts for vast majority of registry access)

  • Anonymous
    September 10, 2010
    Note to those who have noticed the problem with the article title: Many feed readers aren't going to display the tags correctly. This is because of the naively ambiguous nature of RSS, which can contain XML-encoded HTML, but it's up to the feed reader/parser to auto-detect it, which is obviously not reliable. Note to the IEBlog team: You should probably switch to an Atom feed (which unambiguously allows you to specify whether the content of an element contains HTML) if you plan on including tags in titles.

  • Anonymous
    September 10, 2010
    @Brianary: MSDN blogs are available via both RSS and Atom. The Atom URL is here: blogs.msdn.com/.../atom.aspx