Picturefill: Responsive Images for the Web
I gave Picturefill version 2.0 a whirl the other day and was happy with what I saw. Picturefill is a polyfill that makes your web images responsive via either an <img>
tag or a <picture>
element. With a bit of setup time, responsive images easily within reach.
The big plus of Picturefill is it lets the browser decide up front (before downloading an image) what image to download based on information it knows (the user’s viewport size and resolution) and information we provide (how many pixels in width are needed and how many pixels in width are available in each image source). It does the right thing for retina displays as well.
I found the Smashing Magazine article on Picturefill pretty helpful. Since I wasn’t dealing with any art-directed work on the home page on this site where I wanted to implement this polyfill, I went with the <img>
tag approach. Here’s the steps I took:
- I downloaded the polyfill (picturefill.min.js) from Scott Jehl’s site and added the necessary Javascript to my HTML, right below the HTML shiv:
<script src="js/lib/picturefill.min.js" async</script>
- I created a few different sizes of my image for different screen sizes. Because I wanted to make sure my photo looked crisp even on retina screens at larger widths, I created versions of my photo in 4 different widths: 350px, 800px, 1600px, and 2048px. These image paths and widths made up the
srcset
attribute for the<img>
tag. - I checked if there were any media queries set that affected the width of this image at any screen size. In my case, there weren’t. If there were, they would have been needed to be included in the
sizes
attribute within your<img>
tag, to give the browser a heads-up before it decides which image to download. Since my image was always going to be the full width of the viewport at any screen size, I set thesizes
attribute to 100vw, which means 100% of the viewport. For more on vw, see css-tricks. - I added my
<img>
tag in my HTML, replacing the CSS background-image that I was using:
<img sizes="100vw"
srcset="images/lochvale-small.jpg 350w,
images/lochvale-medium.jpg 800w, images/lochvale-large.jpg 1600w,
images/lochvale-huge.jpg 2048w"
alt="Rocky Mountain National Park's Loch Vale">
- I made some CSS changes for my image as well:
.mainWrapper img {
max-width: 100%;
vertical-align: text-bottom;
}
The vertical-align tweak could also be replaced by display: block
. This was needed to avoid getting a thin line of blank space at the bottom of my image.
- I tested the page at different browser widths and on different devices, using my handy Browser-Sync setup. In checking the Chrome Developer Tools’ resources tab, I saw that only one image was downloaded (until I changed the browser width, which triggered another image download). Success!
Here’s an example of Picturefill for a multi-column layout:
<p data-height="356" data-theme-id="0" data-slug-hash="palHn" data-default-tab="result" class='codepen'>
See the Pen <a href='http://codepen.io/sheelah/pen/palHn/'>Picturefill experiment with grid</a> by Sheelah (<a href='http://codepen.io/sheelah'>@sheelah</a>) on <a href='http://codepen.io'>CodePen</a>.
</p>
For more reading on Picturefill also see Eric Portis’s article.