Responsive Images with srcset & Craft

A simple solution to produce responsive images with srcset and Craft.

Tommy recently wrote about responsive background images in Craft, but I wanted to follow up about how we used the <img> element and srcset to build responsive images on this very site (powered by Craft).

We have a Matrix field that powers a lot of the content on the site, and one of the blocks is an image block. A user can upload an image of any size, so I wanted to figure out some way to make that image responsive.

I decided this would be a good opportunity to utilize srcset to output a couple of different image sizes to speed up the page load on smaller devices. We determined that capping the images at 2000 pixels wide would be reasonable, and then I created half and quarter size image crops. Here is what the template looks like:

{% set image = block.image[0] %}
{% set full = (image.width > 2000) ? 2000 : image.width %}
{% set half = round(full / 2) %}
{% set fourth = round(full / 4) %}

  <img src="{{ image.url({ width: half }) }}" alt=""
       srcset="{{ image.url({ width: fourth }) }} {{ fourth }}w,
               {{ image.url({ width: half }) }} {{ half }}w,
               {{ image.url({ width: full }) }} {{ full }}w"
       sizes="(min-width: {{ half + 1 }}px) {{ full }}px,
              (min-width: {{ fourth + 1 }}px) {{ half }}px,

Then, to see what this looks like rendered as HTML with a 2000 pixel image:

  <img src="" alt=""
       srcset=" 500w,
       sizes="(min-width: 1001px) 2000px,
              (min-width: 501px) 1000px,

This is just a super simple example; you could easily get more complex by producing more transforms or using additional media queries. Even though it's a small improvement, images are what produce the most bloat on sites these days.

Trevor is a senior front-end developer who specializes in writing bulletproof code for clients including the World Wildlife Fund and GoPole.

More posts by Trevor