Delivering the right images with the <picture> element

One of the things I started looking at when writing about my Sinclair heritage was how to display images that looked good even when viewed on the latest higher resolution displays.

Simply sending high resolution images regardless of whether they are required or not works of course, but results in web pages much bigger than they need to be for most people, and so slower load times. I’d already given a little thought to this when adding the images for the various project pages, but had cheated then by just serving up high resolution images (sorry).

A lot has been written about how best to handle this particular issue. There is general agreement that something needs to be done, but no agreement as to the best way of doing it. There are two competing proposals – one extending the  <img> element and the other introducing a new <picture> element to work in a similar way to the existing HTML <video> element.

The solution I’ve adopted uses the <picture> element. It seems the best solution of the two to me, but – more significantly – a javascript solution has been devised for implementing it now. There is no functional workaround that uses the proposed <img> element extensions.

If you’re interested in this, a good starting point is A List Apart’s Responsive Images and Web Standards at the Turning Point. A draft of the proposed <picture> element can be found on github: The picture element

The HTML for a given <picture> element  looks something like this:

<picture class=" wp-image-249" title="Sinclair ZX Spectrum">
   <source srcset="IMG_1746-300x224.jpg 1x,
                      IMG_1746-1024x764.jpg 2x">
   <source media="(min-width: 44em)"
              srcset="IMG_1746-1024x764.jpg 1x, IMG_1746.jpg 2x">
   <source media="(min-width: 85em)"
              src="IMG_1746.jpg">
   <!-- Fallback content for non-JS browsers.
           Same img src as the initial, unqualified source element. -->
   <noscript>
        &lt;img src="IMG_1746-300x224.jpg"
                    class="wp-image-249"
                    title="Sinclair ZX Spectrum" /&gt;
   </noscript>
</picture>

Fortunately I don’t have to hand-craft that HTML for each image – it’s generated via my WordPress plugin that looks for and processes standard image elements automatically.

In the above example, the default image size is the smallest – 300×224 pixels (IMG_1746-300×224.jpg). This is the image that is displayed unless the device requesting the page is using a high resolution display (x2) in which case a higher resolution image is sent – 1024×764 pixels (IMG_1746-1024×764.jpg). If the user’s browser window is greater than 44em wide, the default image is the 1024×764 pixel image, and the higher resolution version is the full size version of the image. If the browser window is greater than 88em wide, the full size version of the image is sent no matter what.

Photo: Sinclair ZX Spectrum

This is the image that is referred to in the HTML on this page – you’ll get a different version of it depending on your browser width and screen resolution

The WordPress plugin I’m using is based on one developed by David Newton called wp-picturefill, which itself is based on Scott Jehl’s original Picturefill project. My revised plugin includes the matchMedia polyfill incorporated in Scott Jehl’s original project; some code to get things working when an image is captioned; and a fix for images suddenly disappearing in some browsers (Opera, Firefox) in some instances. It turns out the latter was because the image width was being set to 0. My fix just removed the bit of code that was doing that. At some point I should check whether it was important.