Responsive images in the wild

Tom Cawthorn
Cazoo Technology Blog

--

Images are hard. When creating a webpage they act as one of the most captivating tools in our arsenal. But they’re also very easy to get wrong.

As we covered in an earlier blog post by Ezgi, images can be optimised to create a better user experience. In this post, I’m going to talk about how I like to work with and configure images and how they can be managed in the CMS to avoid some pitfalls up front.

There are a few players involved in getting super slick imagery onto a webpage.

  • A designer creates a beautiful page
  • A content editor fills it with beautiful content
  • An engineer needs to write some beautiful code

Let’s start with the use case. You, an engineer, have been tasked with creating a new page on the website. The design you’re working from is full of fab looking images; there’s a hero, product images, callouts, icons. Where do you start?

I’ll share how I approach breaking images down and planning for responsive behaviour. Here’s my process for calculating aspect ratios, crops and variants.

1. Find your aspect ratios

An aspect ratio is the simplest representation of the width and height of an image. For example, an image that’s 200x100 would have an aspect ratio of 2:1 because the width is twice as long as the height. You can calculate the ratio by dividing the width by the height and simplifying the equation.

In our example, the hero image has a width of 1800px and a height of 800px. Dividing the width by the height returns an aspect ratio of 2.25:1. Cracking.

The ratio looks pretty good because it will be easy to find whole-number pixel sizes for each variant we want to generate e.g.

  • 2250px : 1000px
  • 1800px : 800px
  • 1350px : 600px
  • etc…

Some ratios don’t turn out so well. Let’s say we were working with a width of 1848px and 459px. That equates to 4.0261437908:1, which, quite frankly, makes my skin crawl. Here’s a good time to chat with the designer to see if the sizes can be rounded to something much cleaner to avoid 1/2 px problems.

Our hero also changes aspect ratio at different breakpoints. Work out how the image will behave on your range of supported viewports and run the same calculation. Here are the aspect ratios for our hero:

  • Desktop 2.25:1
  • Tablet 2:1
  • Mobile 1:1

Pro tip! do not couple (by name) your aspect ratios to the devices or viewports they’re used on. The aspect ratio describes the shape of an image, not how or where it will be used! Here’s an example of a naming convention.

2. Set up your crops

Cropping is taking the original image and selecting a window that adheres to the aspect ratio. This could be a small portion of the original image, or even the entire thing — it just needs to fit the ratio. A crop also has a set width and height.

At Cazoo, we’re currently using Prismic CMS, which offers a handy feature where engineers can configure custom crops for an asset. It works by creating an entry with width and height (in pixels) and giving it a name.

Back to our example. The content team have uploaded a hero image that’s 3000px by 2000px. Let’s see what kind of crops we’d set up in the CMS based on the shortest side of that image (2000px).

Awesome. These sizes might be a bit on the wild side but we could go ahead and build the front-end page and start using these image sizes. But it’s not really a good idea to serve a 2000px square to images on mobile! Let’s fix that.

Pro tip! When you’re configuring crop sizes, select the largest size that the image is likely to appear. This might feel odd because you’re generating mobile images that are sized for large or high pixel-density screens, but it’s much easier to make things smaller than it is larger.

3. Generate your variants

We want to give the user the best possible experience on the device they’re using. Images that are larger than necessary will degrade load times and increase user frustration. There are super neat browser tools at our disposal that allow the browser to select from a list of images and these have been described in-depth in an earlier blog post by Ezgi.

We’re really asking ourselves, do we need a picture element, image with srcset or both? We can work that out by asking ourselves some searching questions to pick the best tool for the job.

Does the image change aspect ratio at different viewports?

Yes, it has a different aspect ratio on mobile compared to desktop — use a <picture>

No, it’s always a square — use an <img>

Does the image take up a varied proportion of the viewport at different breakpoints?

Yes, on desktop it’s 50% of the page and on mobile it’s 100% of the page — we’ll need to use the sizes attribute

No, It’s always 100% — we can tell the browser about pixel densities

Is it a very detailed image?

Yes — we’ll probably need multiple versions of the same aspect ratio for retina users

No — we’ll probably get away with a single version

With these questions answered, here’s what I’m thinking for the hero image:

  • We’ll need a picture element so we can serve our different aspect ratios at different breakpoints.
  • It’s a very detailed image so we’ll need a larger version of each image for devices that have a higher pixel density
  • the image always takes up 100% of the viewport width, so we’ll only need to tell the browser about pixel densities

In that case, let’s generate some images!

Srcset + Sizes

The srcset and size attributes are awesome because you off-hand decision making to the web client. Give the browser multiple sizes in the srcset attribute, along with how much of the viewport an image takes up and it will select the most appropriate size for your user. There’s already a bunch of information out there about how to use these, here are some links.

Selecting sizes based on breakpoints

Our page has 3 breakpoints, mobile (500px), tablet (800px) and desktop (1200px).

Here are some example sizes I’d generate for our hero. As a rough rule of thumb, I start off by generating image sizes calculated at the top-end of the breakpoint. For desktop, you might want to create more options or just cap it at something large enough for your most common desktop device.

Generating with a cdn/cms

Some real smart cookies have created some very powerful image tools for just-in-time image modification. An aspect, crop and size can be created ‘on the fly’, and cached by the cdn provider, which removes a lot of the overhead of pre-generating assets ahead of time. Under the hood, Prismic works with Imgix (a CDN provider) to do just that. When we request an image via Imgix, we specify dimensions, scale, quality etc… which makes it super easy and flexible to request images in a variety of formats and sizes.

So in conclusion, create some robust images every time by:

  1. Calculating your aspect ratios
  2. Generating some crops
  3. Resizing your crops to fit your front end

--

--