5 Techniques and Examples for Creating Responsive Images in CSS

Responsive Images in CSS Header

What Is CSS?

Cascading Style Sheets (CSS) are the standard technology for defining the visual styles in webpages. At their most basic, CSS styles text, such as by defining its font size and color. More advanced CSS defines dynamic page layouts, images, and other visual elements, as well as changes to the appearance of a page triggered by JavaScript.

What Are Responsive Images?

Responsive web design (RWD) leverages  flexible layouts, CSS media queries, and flexible images to build webpages, changing webpage layouts according to the visitor’s screen size and orientation.

Responsive images send small, low-resolution versions of images to small screens and large, high-resolution images to larger monitors. That step occurs before the browser starts loading CSS and images, ensuring a crisp look on both device types and downloads of the appropriate images.

This article covers the following topics:

Five Key CSS Techniques for Adding Responsive Images

With CSS’s background property, you can add responsive images to webpage elements to facilitate the repetition of complex images. When combined with media queries, background enables conditional image loading according to factors like screen resolution.

An effective and straightforward approach to making images responsive is by setting an image’s width as a percentage of its parent container. As a result, when the parent container’s size changes, the image’s size will adjust proportionally.

Additionally, for better customization, adding specific classes to images can help manage their responsiveness using @media queries in the CSS. This method provides more flexibility when adjusting image sizes across different devices.

Responsive Images in CSS

1. Defining the Art Direction and Conditional Image Loading With Media Queries

Besides shaping the page layout through conditional image loading, media queries direct art according to the viewport’s width by, for example, ensuring that larger screens download the large.png image in the code below and apply it to <div>, the content’s division element. On the other hand, screen sizes that are below a certain threshold display a smaller image.

.example {
  height: 1200px;
  background-image: url(large.png);
  background-repeat: no-repeat;
  background-size: contain;
  background-position-x: center;
}
@media (max-width: 1000px) {
  body {
    background-image: url(bkg.png);
  }
  .example {
    background-image: url(small.png);
  }
}

2. Providing High-Resolution Images and Art Direction With Media Queries

With media queries, you can create rules for the device-pixel ratio so that users can specify various images for 1x and 2x displays:

@media (min-resolution: 2dppx),
(-webkit-min-device-pixel-ratio: 2)
{
  /* High dpi styles & resources here */
}

The Chrome, Opera, and Firefox browsers support the min-resolution: 2dppx standard. Other browsers, including Android and Safari, require an older prefixed syntax that doesn’t have a dppx unit. Since the browser loads only these styles if the devices match the media queries, be sure to also specify the base-case styles (see below). A major advantage of this technique is that browsers that do not support resolution-specific media queries render images nonetheless.

.sample {
  width: 150px;
  height: 150px;
  background-image: url(pic1x.png);
}
@media (min-resolution: 2dppx), /* Standard syntax */
(-webkit-min-device-pixel-ratio: 2)  /* Safari & Android Browser */
{
  .sample {
    background-size: contain;
    background-image: url(pic2x.png);
  }
}

min-width is another option for displaying images based on viewport size. The browser would not download the image if it doesn’t match the criterion set by the media query. This example mandates that a browser download the background image and apply it to the page body only if the image width is 600 pixels or more:

@media (min-width: 600px) {
  body {
    background-image: url(bkg.png);
  }
}

3. Providing High-Resolution Images With the image-set Function

The CSS image-set() function enhances the behavior of the background property and makes it easier to furnish different image files for various device types. Browsers can choose the most suitable image according to the device’s characteristics, e.g., a 2x image for a 2x display. At times, as in the case of limited network bandwidth, the browser might display a smaller image, e.g., a 1x image for a 2x device. See the code below.

background-image: image-set(
  url(pic1x.jpg) 1x,
  url(pic2x.jpg) 2x
);

Here, the browser loads the appropriate image and scales it to fit the screen or viewport. It assumes that the 2x image is twice the size of the 1x image, scaling the 2x image down to half its original size and ensuring that the image size appears to be the same on the page.

“Optimise

Note that the relatively new image-set() function works on only a few browsers—so far, on  Chrome and Safari only with the -webkit prefix. Hence, be sure to add to your responsive webpages fallback images for browsers that do not support image-set(), like this:

.pic {
  width: 150px;
  height: 150px;
  background-image: url(pic1x.png);
  background-image: -webkit-image-set(
    url(pic1x.png) 1x,
    url(pic2x.png) 2x
  );
  background-image: image-set(
    url(pic1x.png) 1x,
    url(pic2x.png) 2x
  );
}

With this setup, browsers that support image-set() load the correct image; other browsers, the smaller image. The main drawback is that, given the low support for image-set(), most browsers end up displaying the smaller image (pic1x.png).

4. Creating Responsive Images on Fluid Layouts

It can be challenging to create responsive images on fluid layouts. Since images are usually the heaviest elements on a website, they must load before the other elements. Browsers often address this issue by scanning the HTML code for image URLs and starting to load them before performing other tasks, e.g., building the DOM, putting the layout together, and loading external CSS.

Browsers automatically know the environments for the web elements, e.g., viewport size, screen resolution, etc., which are leveraged by responsive webpages for media queries. However, browsers must know the image source even before looking up the rendered size of an image. To adapt images to fluid layouts, you can, for example, define the rendered size of each of the images and communicate that data to the browser.

The sizes attribute serves that purpose. For example, the w descriptors in srcset can specify the number of pixels in each of the source images, based on which the browser then picks the smallest image source whose resolution is high enough for the viewport.

Take a responsive image with three sizes:

  • small.png (240 × 160 pixels)
  • medium.png (480 × 320 pixels)
  • large.png (960 × 640 pixels)

A fluid layout would contain a flexible grid with one column for small viewports, two columns for mid-sized viewports, and three columns for large viewports:

<img srcset="small.png 240w,
medium.png 480w,
Large.png 960w"
sizes="(min-width: 36em) 33.3vw,
100vw"
src="small.png">

By defining the image sources by means of srcset with w descriptors, the above script passes on the actual image widths (in pixels) to the browser. Note that the script defines only image widths because, for simplicity, responsive images usually take into account widths, not heights.

To recap:

  • The width descriptor specifies the pixel count for image sources.
  • The sizes attribute tells the browser the number of pixels required based on the final width of the rendered image. Early on, sizes passes on the page layout to the browser, which can then choose the appropriate image source before rendering the CSS code for the page.

To learn how to automate tasks related to responsive images, see the documentation on combining responsive automation with other Cloudinary features. 

5. Specifying the Maximum Width Values

Web designers and developers often create responsive images with the max-width property, which specifies an element’s maximum width. No images can be wider than the max-width value, e.g., an image with a width of 1,000 pixels cannot generate an image of 1,200 pixels. Likewise, if the screen width is 640 pixels, the browser does not display the full image.

Therefore, be sure to set the max-width value to 100% so as to shrink the image to match the device:

img {
  max-width: 100%;
  width: 1000px; // Assume this is the default size.
}

The image is now fluid on all devices that are less than 1,000 pixels wide. For wider devices, however, the browser does not enlarge the image to fit the screen, which is the main drawback of max-width given its effect on image responsiveness.

Automating Responsive Images With Cloudinary

A cloud-based service for managing images and videos, Cloudinary offers a generous free-forever subscription plan. While on that platform, you can upload images and apply built-in effects, filters, and modifications. You can also create image effects that are difficult or impossible to produce with just CSS.

Cloudinary makes it simple to deliver responsive images by doing the following:

QUICK TIPS
Tamas Piros
Cloudinary Logo Tamas Piros

Tips from the expert

In my experience, here are tips that can help you better implement responsive images in CSS to reduce bandwidth and maintain high visual quality:

  1. Leverage the image-set() function for higher flexibility
    The image-set() function in CSS allows you to define multiple versions of a background image with different resolutions or quality levels. Use this function to dynamically serve 1x, 2x, or even 3x images for varying device pixel ratios, ensuring the browser selects the most appropriate image based on the screen’s capabilities. This approach reduces bandwidth for devices that don’t need high-resolution images while ensuring sharp visuals for high-DPI screens.
  2. Combine min-resolution and min-width in media queries for precision
    Use both min-resolution and min-width media queries together to deliver images that fit not only the screen size but also the screen resolution. For example, use higher-quality images only for large displays with high pixel densities and fallback to lower-quality images for smaller screens or low-DPI devices. This ensures that no bandwidth is wasted on high-resolution images when they aren’t needed.
  3. Use CSS’s background-size for responsive scaling
    When using background images, set background-size: contain or background-size: cover to control how images scale within their containers. background-size: contain ensures the image fits within the container without being cropped, while background-size: cover ensures the image covers the entire container, maintaining its proportions. These properties help you avoid distorted or pixelated backgrounds in fluid layouts.
  4. Implement responsive images with CSS @media queries for art direction
    Use CSS media queries to change the background image for different viewport sizes and orientations. Define a base image in the default CSS and then override it with specific images for breakpoints (e.g., replace a wide desktop image with a vertically cropped version for mobile screens). This technique lets you tailor each image to different layouts, ensuring the right focus and visual appeal.
  5. Use max-width: 100% and height: auto for fluid scaling
    For inline images (e.g., using <img> elements), set max-width: 100% and height: auto in your CSS. This ensures that the image scales proportionally within its container, maintaining its aspect ratio without overflow. This technique is especially useful for making images fit within columns in a responsive grid.
  6. Test image quality across varying device pixel ratios
    Use a combination of image-set() and dppx values to serve high-quality images to devices with higher pixel densities. Ensure that your image quality is appropriate for 1x, 1.5x, and 2x resolutions, as serving overly high-quality images to standard screens wastes bandwidth and leads to longer load times.
  7. Create responsive background images using CSS object-fit
    Use the object-fit property (cover or contain) for responsive background images that maintain their aspect ratio. This is a powerful alternative to background-size when dealing with inline <img> tags, ensuring consistent rendering without needing to use background-image properties.
  8. Implement Cloudinary’s dynamic transformations for automation
    When using Cloudinary, dynamically generate images using parameters like w_auto (for automatic width) and f_auto (for format optimization) in your CSS background-image URLs. This allows Cloudinary to generate the optimal image size based on the container’s width, saving bandwidth while preserving image quality.
  9. Use responsive image placeholders for a smooth loading experience
    Use a low-quality image placeholder (LQIP) or a blurred version of your main image as a background image first, then replace it with the high-quality image once it loads. This approach is visually engaging and prevents users from experiencing blank or broken images while the full image downloads.
  10. Combine CSS clip-path and shape-outside for creative image cropping
    Use CSS clip-path or shape-outside properties to crop images responsively without modifying the source file. This technique lets you create circular, polygonal, or other creative shapes for images based on the layout context. For example, create circular thumbnails for profile images that maintain their shape and aspect ratio across different screen sizes.

Implementing these tips will help you create responsive images in CSS that are visually dynamic, highly performant, and tailored to the needs of different devices, ensuring an optimal experience for all users.

Last updated: Oct 1, 2024