1/23/2014 - 7:00 PM

Responsive Images

Responsive Images

This demonstrates a responsive image technique using picturefill.js, currently one of the best responsive image solutions available. Essentially it mimics an exciting web standard on the horizon, the proposed picture element, to deliver images at an appropriate size (and bandwidth!) for a given screen size. Read more about responsive image solutions from the filament group.

My demonstration here always makes use of "art direction." I've manually cropped, zoomed, and changed the focal point of each image. View this example in a new window to resize the display.

<!DOCTYPE html>
<html class="no-js">
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Responsive Images with picturefill.js</title>

        	body {
        		font-family: sans-serif;
        		color: #666;
        	h1 {
        		font-weight: normal;
                margin: 0 0 10px;
        	#wrapper {
        		max-width: 960px;
        		margin: 20px auto;
        		padding: 0 15px;
        	.image {
        		width: 60%;
        		float: left;
        		margin-right: 25px;
        	img {
        		max-width: 100%;

    	<div id="wrapper">
    		<h1>Bacon expert weighs in on responsive images</h1>
    		<span class="image" data-picture data-alt="(South Sheet) Mexico The British Possessions In North America And The United States.">
		        <span data-src="pig-small.jpg"></span>
		        <span data-src="pig-medium.jpg"     data-media="(min-width: 400px)"></span>
		        <span data-src="pig-large.jpg"      data-media="(min-width: 800px)"></span>

		        <!-- fallback in case JS breaks or something -->
		            <img src="pig-small.jpg" alt="(South Sheet) Mexico The British Possessions In North America And The United States.">
    		<p>Bacon ipsum dolor sit amet meatball filet mignon shoulder, tenderloin kevin shankle pork tri-tip spare ribs chuck leberkas porchetta frankfurter tail corned beef. Biltong bresaola tri-tip fatback cow pancetta. Jerky ball tip biltong short ribs shankle filet mignon venison bacon kielbasa rump. Rump drumstick flank short ribs, turducken ham hock t-bone turkey pork loin. Ham rump short ribs capicola shank. Flank boudin biltong rump swine ground round tongue tri-tip short ribs capicola tenderloin pig beef ribs. Shankle short loin ham swine prosciutto turducken.</p>
    		<p>Salami beef rump chuck swine. Turducken pancetta pork prosciutto sausage jerky, doner kevin t-bone brisket pastrami rump ball tip biltong. Pancetta tail pig capicola pork loin, turducken tri-tip. Turducken chuck salami boudin meatball leberkas turkey.</p>
		<script src="picturefill.js"></script>
/*! Picturefill - Responsive Images that work today. (and mimic the proposed Picture element with span elements). Author: Scott Jehl, Filament Group, 2012 | License: MIT/GPLv2 */

(function( w ){

        // Enable strict mode
        "use strict";

        w.picturefill = function() {
                var ps = w.document.getElementsByTagName( "span" );

                // Loop the pictures
                for( var i = 0, il = ps.length; i < il; i++ ){
                        if( ps[ i ].getAttribute( "data-picture" ) !== null ){

                                var sources = ps[ i ].getElementsByTagName( "span" ),
                                        matches = [];

                                // See if which sources match
                                for( var j = 0, jl = sources.length; j < jl; j++ ){
                                        var media = sources[ j ].getAttribute( "data-media" );
                                        // if there's no media specified, OR w.matchMedia is supported
                                        if( !media || ( w.matchMedia && w.matchMedia( media ).matches ) ){
                                                matches.push( sources[ j ] );

                        // Find any existing img element in the picture element
                        var picImg = ps[ i ].getElementsByTagName( "img" )[ 0 ];

                        if( matches.length ){
                                var matchedEl = matches.pop();
                                if( !picImg || picImg.parentNode.nodeName === "NOSCRIPT" ){
                                        picImg = w.document.createElement( "img" );
                                        picImg.alt = ps[ i ].getAttribute( "data-alt" );
                                else if( matchedEl === picImg.parentNode ){
                                        // Skip further actions if the correct image is already in place

                                picImg.src = matchedEl.getAttribute( "data-src" );
                                matchedEl.appendChild( picImg );
                        else if( picImg ){
                                picImg.parentNode.removeChild( picImg );

        // Run on resize and domready (w.load as a fallback)
        if( w.addEventListener ){
                w.addEventListener( "resize", w.picturefill, false );
                w.addEventListener( "DOMContentLoaded", function(){
                        // Run once only
                        w.removeEventListener( "load", w.picturefill, false );
                }, false );
                w.addEventListener( "load", w.picturefill, false );
        else if( w.attachEvent ){
                w.attachEvent( "onload", w.picturefill );

}( this ));