Responsive Images with srcset & Craft

Trevor Davis, Former Front-End Development Technical Director

Article Categories: #Code, #Front-end Engineering

Posted on

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) %}

<figure>
  <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,
              100vw"
  >
</figure>

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

<figure>
  <img src="https://static.viget.com/1000.png" alt=""
       srcset="https://static.viget.com/500.png 500w,
               https://static.viget.com/1000.png 1000w,
               https://static.viget.com/2000.png 2000w"
       sizes="(min-width: 1001px) 2000px,
              (min-width: 501px) 1000px,
              100vw"
  >
</figure>

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.

Related Articles