Implementing Responsive Images

Responsive image on mobile devices, laptop, and desktop

When developing a website, implementing responsive designs means handling responsive images, the ones that can adapt to user devices and browsers.

Uploadcare's image processing helps you prepare a virtually infinite number of image versions to use with Responsive Images. This article describes the possible image processing approaches tailored to specific screens with HTML and CSS.

Responsive Images via HTML

Using the img Element

Here’s a simple way to make an image responsive with HTML: use the <img> element and set the width as a percentage for <img> in CSS.

The image width adapts to the width of the container.

Live example #1

<img src="https://ucarecdn.com/:uuid/-/resize/1000x/">

<style>
 img {
   width: 100%;
   height: auto;
 }
</style>html

Tip: Use Chrome DevTools, device mode and network tab to see how the image changes for this and ensuing examples.

In this example, the original image size is 4928x3280px, and the file size is 1.85 MB. When we obtain a smaller version of the image using Uploadcare CDN resize operator, the image width is reduced to 1000px, and the file size is reduced to just 125 KB.

HiDPI Screens and srcset

Set the version of the image for HiDPI screens with the srcset attribute of the <img> element and the x descriptor.

Live example #2

<img
    src="https://ucarecdn.com/:uuid/-/resize/1000x/1.jpg"
    srcset="https://ucarecdn.com/:uuid/-/resize/2000x/-/quality/lightest/1.jpg 2x">html

For devices with a pixel ratio equal to 2, you need a double-sized image.

Tip: use the quality operator to reduce the quality of an image in cases when high quality is not necessary.

On devices with pixel ratio equal to 2, we can get a version of the image that is 2000px wide and weighs 200 KB.

That’s pretty good, but still too big for loading onto mobile devices. For example, for the iPhone 5, an image width of 640px is enough because the screen width is 320px and the DPR is 2.

Our 640px picture weighs only 59.5 KB.

Variable Widths, srcset, and sizes

To load an image that fits certain screen parameters, use the w descriptor in srcset as well as the sizes attribute.

Live example #3

<img src="https://ucarecdn.com/:uuid/-/resize/1000x/fallback.jpg"
     srcset="https://ucarecdn.com/:uuid/-/resize/320x/320.jpg 320w,
             https://ucarecdn.com/:uuid/-/resize/450x/450.jpg 450w,
             https://ucarecdn.com/:uuid/-/resize/640x/640.jpg 640w,
             https://ucarecdn.com/:uuid/-/resize/750x/750.jpg 750w,
             https://ucarecdn.com/:uuid/-/resize/800x/800.jpg 800w,
             https://ucarecdn.com/:uuid/-/resize/900x/900.jpg 900w,
             https://ucarecdn.com/:uuid/-/resize/1000x/-/quality/lighter/1000.jpg 1000w,
             https://ucarecdn.com/:uuid/-/resize/1200x/-/quality/lighter/1200.jpg 1200w,
             https://ucarecdn.com/:uuid/-/resize/1500x/-/quality/lighter/1500.jpg 1500w,
             https://ucarecdn.com/:uuid/-/resize/1600x/-/quality/lighter/1600.jpg 1600w,
             https://ucarecdn.com/:uuid/-/resize/2000x/-/quality/lightest/2000.jpg 2000w"
     sizes="(min-width: 1000px) 50vw, 90vw">html

We tell the browser that image https://ucarecdn.com/:uuid/-/resize/320x/320.jpg has a width of 320px, image https://ucarecdn.com/:uuid/-/resize/640x/640.jpg is 640px wide, and so on. The browser will select an image depending on the viewport as well as the device pixel ratio.

In sizes we can set information about what part of the viewport will be occupied by the image.

sizes="(min-width: 1000px) 50vw, 90vw"

On screens with a width of 1000px, an image takes 50% of the width. In other cases, i.e. smaller screens, it will occupy most of its width.

The picture Element Superpowers

The <picture> element is a new HTML element, and it extends the <img> element. It contains multiple <source> elements that have an srcset attribute and can have sizes and media attributes. The media attribute allows you to specify media queries like in CSS. The browser will select the most suitable source.

Let’s see how we can use it.

We have a wide image, and in previous examples, it looks on smartphones like it does on a desktop.

Landscape-oriented image resized on smartphone

But what we want to see is a tall and thin image in a portrait orientation on smartphones.

Portrait-oriented resize works for smartphone better

We pick <img> code from the previous example and add a <picture> container with one <source> element.

Live example #4

<picture>
    <source
        srcset="https://ucarecdn.com/:uuid/-/scale_crop/320x569/center/320-569.jpg 320w,
                https://ucarecdn.com/:uuid/-/scale_crop/640x1138/center/-/quality/lightest/640-1138.jpg 640w,
                https://ucarecdn.com/:uuid/-/scale_crop/450x800/center/450-800.jpg 450w,
                https://ucarecdn.com/:uuid/-/scale_crop/900x1600/center/-/quality/lightest/900-1600.jpg 900w"
        sizes="90vw"
        media="(max-width: 450px) and (orientation: portrait)">

    <img src="https://ucarecdn.com/:uuid/-/resize/1000x/fallback.jpg"
        srcset="https://ucarecdn.com/:uuid/-/resize/320x/320.jpg 320w,
                https://ucarecdn.com/:uuid/-/resize/450x/450.jpg 450w,
                https://ucarecdn.com/:uuid/-/resize/640x/640.jpg 640w,
                https://ucarecdn.com/:uuid/-/resize/750x/750.jpg 750w,
                https://ucarecdn.com/:uuid/-/resize/800x/800.jpg 800w,
                https://ucarecdn.com/:uuid/-/resize/900x/900.jpg 900w,
                https://ucarecdn.com/:uuid/-/resize/1000x/-/quality/lighter/1000.jpg 1000w,
                https://ucarecdn.com/:uuid/-/resize/1200x/-/quality/lighter/1200.jpg 1200w,
                https://ucarecdn.com/:uuid/-/resize/1500x/-/quality/lighter/1500.jpg 1500w,
                https://ucarecdn.com/:uuid/-/resize/1600x/-/quality/lighter/1600.jpg 16000w,
                https://ucarecdn.com/:uuid/-/resize/2000x/-/quality/lightest/2000.jpg 2000w"
        sizes="(min-width: 1000px) 50vw, 90vw">
</picture>html

The media attribute of the <source> element adds a condition that if screen has a width of less than 450px and the orientation is portrait, the browser must select the image from the srcset attribute of <source>.

Tip: Use the scale_crop operator or the crop operator from Uploadcare Image CDN to get a custom part of an image.

Art Direction

Art direction is the focus of the main subject of the image. It is important for smaller screens. On the large screen, we can show the full image, but on a smaller screen, we want to show just the main part of the image.

In our example, we want to show just the head of the chameleon on smartphones.

Horizontal image resized on a smartphone screen

Take the previous example and just change the scale_crop operator to the crop operator with the resize operator.

Live example #5

<picture>
    <source
        srcset="https://ucarecdn.com/:uuid/-/crop/2048x1365/1345,670/-/resize/320x/320.jpg 320w,
                https://ucarecdn.com/:uuid/-/crop/2048x1365/1345,670/-/resize/640x/640.jpg 640w,
                https://ucarecdn.com/:uuid/-/crop/2048x1365/1345,670/-/resize/450x/450.jpg 450w,
                https://ucarecdn.com/:uuid/-/crop/2048x1365/1345,670/-/resize/900x/900.jpg 900w"
        sizes="90vw"
        media="(max-width: 450px) and (orientation: portrait)">

    <img src="https://ucarecdn.com/:uuid/-/resize/1000x/fallback.jpg"
        srcset="https://ucarecdn.com/:uuid/-/resize/320x/-/quality/lighter/320.jpg 320w,
                https://ucarecdn.com/:uuid/-/resize/450x/-/quality/lighter/450.jpg 450w,
                https://ucarecdn.com/:uuid/-/resize/640x/-/quality/lighter/640.jpg 640w,
                https://ucarecdn.com/:uuid/-/resize/750x/-/quality/lighter/750.jpg 750w,
                https://ucarecdn.com/:uuid/-/resize/800x/-/quality/lighter/800.jpg 800w,
                https://ucarecdn.com/:uuid/-/resize/900x/-/quality/lighter/900.jpg 900w,
                https://ucarecdn.com/:uuid/-/resize/1000x/-/quality/lighter/1000.jpg 1000w,
                https://ucarecdn.com/:uuid/-/resize/1200x/-/quality/lighter/1200.jpg 1200w,
                https://ucarecdn.com/:uuid/-/resize/1500x/-/quality/lighter/1500.jpg 1500w,
                https://ucarecdn.com/:uuid/-/resize/1600x/-/quality/lighter/1600.jpg 16000w,
                https://ucarecdn.com/:uuid/-/resize/2000x/-/quality/lightest/2000.jpg 2000w"
        sizes="(min-width: 1000px) 50vw, 90vw">
</picture>html

Tip: Use the crop operator from Uploadcare Image CDN to get the main part of an image and use the resize operator after that.

https://ucarecdn.com/:uuid/-/crop/1800x1200/1090,1220/-/resize/900x/

Breakpoints

The w descriptor in srcset and the sizes attribute is handy; the browser will select the suitable image. But what if we have a few breakpoints in our responsive design and want to set images that are suitable for them? We can use several <source> elements with media attributes, one for each breakpoint.

Live example #6

<picture>
    <source
        srcset="https://ucarecdn.com/:uuid/-/resize/1000x/1000.jpg 1000w,
                https://ucarecdn.com/:uuid/-/resize/2000x/-/quality/lightest/2000.jpg 2000w"
        sizes="(min-width: 1000px) 60vw, 90vw"
        media="(min-width: 750px)">

    <source
        srcset="https://ucarecdn.com/:uuid/-/resize/750x/750.jpg 1x,
                https://ucarecdn.com/:uuid/-/resize/1500x/-/quality/lightest/1500.jpg 2x"
        media="(min-width: 450px)">

    <source
        srcset="https://ucarecdn.com/:uuid/-/resize/450x/450.jpg 1x,
                https://ucarecdn.com/:uuid/-/resize/900x/-/quality/lightest/900.jpg 2x"
        media="(orientation: landscape)">

    <source
        srcset="https://ucarecdn.com/:uuid/-/scale_crop/450x800/center/450-800.jpg 1x,
                https://ucarecdn.com/:uuid/-/scale_crop/900x1600/center/-/quality/lightest/900-1600.jpg 2x"
        media="(orientation: portrait)">

    <img src="https://ucarecdn.com/:uuid/-/resize/1000x/fallback.jpg">
</picture>html

Responsive Images via CSS

background-image

Responsive images may not be a part of HTML content. It can be just a decoration or background for content. In the latter case, developers use the background-image property in CSS.

We can set different versions of an image with breakpoints using CSS media queries.

We set versions for HiDPI screens with the image-set() CSS function. By using this function, we can insert multiple images that will be set for normal and HiDPI screens.

background-image: image-set(
    url("https://ucarecdn.com/:uuid/-/scale_crop/450x800/center/1.jpg") 1x,
    url("https://ucarecdn.com/:uuid/-/scale_crop/900x1600/center/-/quality/lightest/2.jpg") 2x
);

background-image , Sass version

We wrote a Sass function for getting a URL of an image that was uploaded to Uploadcare:

Conclusion

Modern HTML and CSS standards offer ready-made solutions in order to tell a browser which image to load for the current screen. We can tell the browser to load a large version of an image for large screens and a smaller version of the same image for smartphones to save internet traffic by using srcset and <picture>.

You must prepare a few versions of an image. This can be difficult and time-consuming, but Uploadcare Image CDN will help. You can just upload an image file and use CDN operators for on-the-fly image processing.

There is one other problem: a lot of code. In our example, for <picture>, we have nine versions of an image and 4 <source> elements. 17 lines of code (without comments) to load one image! In a real-life project, you can have even more code.