Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Adds support for -based resolution switching on source elements.

  • Loading branch information...
commit 782fcfd25b9536bfdbcce88d965eaa193a9980b1 1 parent 0d793ea
@Wilto authored
View
BIN  external/imgs/extralarge.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  external/imgs/extralarge2x.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  external/imgs/large.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  external/imgs/large2x.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  external/imgs/medium.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  external/imgs/medium2x.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  external/imgs/small.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  external/imgs/small2x.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
55 index.html
@@ -16,19 +16,48 @@
<h1>Picturefill: A &lt;picture&gt; element polyfill</h1>
<p>For more info: <a href="http://github.com/scottjehl/picturefill">see project home.</a></p>
-
- <picture alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
- <!-- <source src="external/imgs/small.jpg"> -->
- <source src="external/imgs/small.jpg">
- <!-- <source src="external/imgs/medium.jpg" media="(min-width: 400px)"> -->
- <source src="external/imgs/medium.jpg" media="(min-width: 400px)">
- <!-- <source src="external/imgs/large.jpg" media="(min-width: 800px)"> -->
- <source src="external/imgs/large.jpg" media="(min-width: 800px)">
- <!-- <source src="external/imgs/extralarge.jpg" media="(min-width: 1000px)"> -->
- <source src="external/imgs/extralarge.jpg" media="(min-width: 1000px)">
- <!-- Fallback content for non-JS browsers. Same img src as the initial, unqualified source element. -->
- <noscript><img src="external/imgs/small.jpg" alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia"></noscript>
- </picture>
+ <section>
+ <h1><code>source</code> elements using both <code>media</code> and <code>srcset</code> attributes</h1>
+ <p>This markup pattern is further detailed in the <a href="http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2012-May/036160.html">original proposal</a> by Florian Rivoal.</p>
+ <p>This syntax combines the resolution switching of <code>srcset</code> with <code>picture</code>’s ability to tailor sources to the viewport. This has a couple of major benefits over the originally-propsed <code>picture</code> element:</p>
+ <ul>
+ <li>Less verbose and more readable syntax, especially considering the vendor prefixing that comes along with <code>min-device-pixel-ratio</code>. Determining viewport-appropriate sources is handled through <code>media</code> attributes as expected, while serving that viewport-appropriate source at the correct <em>resolution</em> is done with <code>srcset</code>.</li>
+ <li>A native implementation would allow us to apply the original intrinsic dimensions of the <code>1x</code> source to the higher-resolution sources rather than simply delivering an image twice the size. This polyfill simply divides the image’s intrinsic width against the screen resolution (1x, 2x, etc.), though I’m sure this can be handled more intelligently in a native implementation.</li>
+ <li>By sandboxing the resolution in this new attribute, we allow the browser to intervene without compromising the effectiveness of media queries. The decision to serve higher-resolution images based on available bandwidth is a decision best left in the hands of the browser. <code>srcset</code> allows us to define a set of <em>suggested</em> sources based on resolution, while a user setting or automated bandwidth detection in the browser could still intervene. This approach prevents us from breaking the intended “absolute” terms of media queries.</li>
+ </ul>
+ <picture alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
+ <!-- <source srcset="external/imgs/small.jpg 1x, external/imgs/small2x.jpg 2x"> -->
+ <source srcset="external/imgs/small.jpg 1x, external/imgs/small2x.jpg 2x">
+ <!-- <source media="(min-width: 400px)" srcset="external/imgs/medium.jpg 1x, external/imgs/medium2x.jpg 2x"> -->
+ <source media="(min-width: 400px)" srcset="external/imgs/medium.jpg 1x, external/imgs/medium2x.jpg 2x">
+ <!-- <source media="(min-width: 800px)" srcset="external/imgs/large.jpg 1x, external/imgs/large2x.jpg 2x"> -->
+ <source media="(min-width: 800px)" srcset="external/imgs/large.jpg 1x, external/imgs/large2x.jpg 2x">
+ <!-- <source media="(min-width: 1000px)" srcset="external/imgs/extralarge.jpg 1x, external/imgs/extralarge2x.jpg 2x"> -->
+ <source media="(min-width: 1000px)" srcset="external/imgs/extralarge.jpg 1x, external/imgs/extralarge2x.jpg 2x">
+
+ <!-- Fallback content for non-JS browsers. Same img src as the initial, unqualified source element. -->
+ <noscript><img src="external/imgs/small.jpg" alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia"></noscript>
+ </picture>
+ </section>
+
+ <section>
+ <h1><code>source</code> elements using <code>media</code> attributes only</h1>
+ <p>Does not perform any resolution switching.</p>
+ <picture alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
+ <!-- <source src="external/imgs/small.jpg"> -->
+ <source src="external/imgs/small.jpg">
+ <!-- <source src="external/imgs/medium.jpg" media="(min-width: 400px)"> -->
+ <source src="external/imgs/medium.jpg" media="(min-width: 400px)">
+ <!-- <source src="external/imgs/large.jpg" media="(min-width: 800px)"> -->
+ <source src="external/imgs/large.jpg" media="(min-width: 800px)">
+ <!-- <source src="external/imgs/extralarge.jpg" media="(min-width: 1000px)"> -->
+ <source src="external/imgs/extralarge.jpg" media="(min-width: 1000px)">
+
+ <!-- Fallback content for non-JS browsers. Same img src as the initial, unqualified source element. -->
+ <noscript><img src="external/imgs/small.jpg" alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia"></noscript>
+ </picture>
+ </section>
+
</body>
</html>
View
32 picturefill.js
@@ -49,14 +49,40 @@
var picImg = ps[ i ].getElementsByTagName( "img" )[ 0 ];
if( matches.length ){
-
+ // Grab the most appropriate (last) match.
+ var match = matches.pop(),
+ srcset = match.getAttribute( "srcset" );
+
if( !picImg ){
picImg = w.document.createElement( "img" );
picImg.alt = ps[ i ].getAttribute( "alt" );
ps[ i ].appendChild( picImg );
}
-
- picImg.src = matches.pop().getAttribute( "src" );
+
+ if( srcset ) {
+ var screenRes = w.devicePixelRatio || 1, // Is it worth looping through reasonable matchMedia values here?
+ sources = srcset.split(","); // Split comma-separated `srcset` sources into an array.
+
+ for( var res = sources.length, r = res - 1; r >= 0; r-- ) { // Loop through each source/resolution in `srcset`.
+ var source = sources[ r ].replace(/^\s*/, '').replace(/\s*$/, '').split(" "), // Remove any leading whitespace, then split on spaces.
+ resMatch = parseInt( source[1], 10 ); // Parse out the resolution for each source in `srcset`.
+
+ if( resMatch == screenRes && picImg.getAttribute( "src" ) !== source[0] ) {
+ var newImg = document.createElement("img");
+
+ newImg.src = source[0];
+
+ // When the image is loaded, set a width equal to that of the original’s intrinsic width divided by the screen resolution:
+ newImg.onload = function() {
+ this.width = ( this.cloneNode( true ).width / screenRes ); // Clone the original image into memory so the width is unaffected by page styles
+ }
+ picImg.parentNode.replaceChild( newImg, picImg );
+ }
+ }
+ } else {
+ // No `srcset` in play, so just use the `src` value:
+ picImg.src = match.getAttribute( "src" );
+ }
}
else if( picImg ) {
ps[ i ].removeChild( picImg );
Please sign in to comment.
Something went wrong with that request. Please try again.