A polyfill for proposed behavior of the picture element, which does not yet exist, but should. :)
- Author: Scott Jehl (c) 2012
- License: MIT/GPLv2
Notes: For active discussion of the picture element, see http://www.w3.org/community/respimg/. While this code does work, it is intended to be used only for example purposes until either:
A) A W3C Candidate Recommendation for is released
B) A major browser implements
Demo URL: http://scottjehl.github.com/picturefill/
Note: The demo only polyfills
picture support for browsers that support CSS3 media queries, but it includes (externally) the matchMedia polyfill which makes matchMedia work in
media-query-supporting browsers that don't have
matchMedia, or at least allows media types to be tested in most any browser.
matchMedia and the
matchMedia polyfill are not required for
picture to work, but they are required to support the
media attributes on
Size and delivery
picturefill.js compresses to around 498bytes (~0.5kb), after minify and gzip. To minify, you might try these online tools: [Uglify]:(http://marijnhaverbeke.nl/uglifyjs), [Yahoo Compressor]:(http://refresh-sf.com/yui/), or Closure Compiler. Serve with gzip compression.
Picturefill performs a html5-shiv style workaround to get
picture elements recognized in IE browsers. Because of that, you must reference it from the
head of your document. If you'd prefer not referencing it from
head, you'll need to at least call
document.createElement("picture"); document.createElement("source"); somewhere in the head of your document, and then you can load
picturefill.js whenever you want.
Markup pattern and explanation
While the proposed markup for the
picture element is quite simple, enabling its use in browsers that don't yet support it requires a few unfortunate tweaks. The following markup pattern is intended to "bulletproof" existing browser support for
picture without interfering with future native implementations.
<picture alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia"> <!-- <source src="small.jpg"> --> <source src="small.jpg"> <!-- <source src="medium.jpg" media="(min-width: 400px)"> --> <source src="medium.jpg" media="(min-width: 400px)"> <!-- <source src="large.jpg" media="(min-width: 800px)"> --> <source src="large.jpg" media="(min-width: 800px)"> <!-- Fallback content for non-JS browsers. Same src as the initial source element. --> <noscript><img src="small.jpg" alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia"></noscript> </picture>
Notes on the markup above...
altattribute is used as alternate text for the generated
pictureelement can have any number of
sourceelements. The above example may contain more than the average situation would call for.
sourceelement must have a
srcattribute specifying the image path.
- It's generally a good idea to include one source element with no
mediaqualifier, so it'll apply everywhere.
sourceelement can have an optional
mediaattribute to make it apply in different media settings. Both media types and queries can be used, like any
mediaattribute, but support for media queries depends on the browser (unsupporting browsers fail silently).
matchMediapolyfill (included in
/external) is necessary to support the
mediaattribute across browsers, even in browsers that support media queries, although it is becoming more widely supported in new browsers.
- To ensure
sourceelements are recognized in browsers like iOS4.3, Android 2.x, and IE9,
sourceelements should be preceded by a comment containing that
sourceelement's markup. See the support table for information on which browsers rely on these comments (these browsers remove
sourceelements from the DOM at load, so the comments provide a fallback).
Picturefill supports a broad range of browsers and devices (there are currently no known unsupported browsers), provided that you stick with the markup conventions provided.
The following table covers some of the major platforms tested so far and their mode of support for the picture element, and picturefill.
|Android 1.6 Webkit||Full|
|Android 2.1 Webkit||Comment fallbacks used|
|Android 2.2 Webkit||Comment fallbacks used|
|Android 2.3 Webkit||Comment fallbacks used|
|Android 4.x Webkit||Full|
|iOS 4.3 Safari||Comment fallbacks used|
|iOS 5.0 Safari||Full|
|Chrome Mac (tested v17)||Full|
|Opera Mac Desktop (tested v11)||Full|
|Firefox Mac Desktop (tested v3.0+)||Full|
|IE 6||Full (*no media query support, though)|
|IE 7||Full (*no media query support, though)|
|IE 8||Full (*no media query support, though)|
|IE 9||Comment fallbacks used|
...More testing wanted! :)