Watercolor image of designer's desk with various painings hanging on the wall. A desktop monitor showing a colorful flower and bird filled background. Around it sit a laptop, tablet, and various phones all showing the same image at different resolutions. There are also various sketch pas and pens & pencils laying on the desk.

Responsive Background Images With or Without image-set(): The Proven Way

Do a search for “responsive background images” on the web. Go on and do the search, I’ll wait.

Oh, you’re back. Notice anything strange? For example, nobody can decide on what this means, how to do it, or even how to do it easily? You’re not alone. Fact is, the vast majority of sites have incorrect answers for generating responsive background images the way the img tag with srcset and sizes attributes work. This post puts it all to rest with the definitive answer a few mention as an “option” rather than the answer. Let’s start with a definition.

What are responsive background images?

There is some clear confusion over what exactly constitutes a responsive background image. Many declare them, simply, as the act of using a background image and that they are inherently responsive. Others define them as the filling of a given space by setting the background-size property to cover or contain. This inconsistency makes the entire idea confusing; They define the background styling an HTML element but not making the background responsive.

Responsive background images are to background images what the srcset and sizes attributes are to the img tag. Mozilla’s web development docs define that as

images that work well on devices with widely differing screen sizes, resolutions, and other such features

MDN

In other words – just adding a background image to an element or even having it fill a given space does not constitute a responsive background image… but it does contribute to it.

Image-Set() Is For Pixel Density & Type Support, Not Responsiveness

Many posts will erroneously tell you to use image-set() to make background images responsive. This is misleading at best. image-set() was not meant to be used to provide different images at differing device screen widths. It is meant to provide different images based on the pixel density of the device. I already know what some are going to say…

But pixel density does fit with device size!

Unfortunately, you would be wrong. Using pixel density (such as DPI or 1x, 2x, 3x, etc) as a way to target a mobile device vs a tablet vs a desktop won’t work. While most mobile phones do use higher pixel density than most desktop monitors, others do as well. A number of tablets also have higher pixel density and Apple’s high DPI Retina display is (or was) available on their desktop machines as well. Just because the vast majority of the rest of the industry did not go in that direction does not mean you should simply assume only certain devices make use.

What does this all mean? Using image-set() by itself as a way to define device-specific images is not likely to get the results you expect and does not mean your background images are responsive. The following code will not hit the majority of cases you would expect to hit when setting different sized images for mobile devices, tablets, and desktops:

CSS
// Don't use this to target mobile, tablet, or desktop devices
.some-element {
  background-image: image-set(
    url("/path/to/regular-image.webp") 1x,
    url("/path/to/regular-image.2x.webp") 2x
  );
}

Responsive Background Images Revealed: The Proven & Tested Solution

While various articles and StackOverflow (SO) question answers may tell you to multiple background-image properties (possibly using some JavaScript-set class), use image-set() by itself, or some other JavaScript (JS) to swap-out images, DON’T. They all have huge downsides. Everything from loading multiple versions of image, which uses even more bandwidth and loading a single image, to delaying the loading of images to increasing the amount of blocking scripts unnecessarily. There is a much better, pure CSS way to handle responsive background images.

The tested and proven way is to use media queries. Yep, I said it. You may not like it, but as of 2024, it’s the primary way to generate responsive background images that target different device widths the your breakpoints and img tags do. Here is the tested and proven solution, JS involved:

CSS
/* Use your own breakpoints or, better yet, generate
   this dynamically within your CMS (such as through
   an extension/plugin or theme):
 */

// Mobile first! Up to 767px:
.some-element {
  background-image: url("/path/to/image-767.webp");
}

// Tablet (768px to 1023px)
@media (min-width: 768px) {
  .some-element {
    background-image: url("/path/to/image-1023.webp");
  }
}

// Smaller laptops and tablet in landscape (1024px to 1279px)
@media (min-width: 1024px) {
  .some-element {
    background-image: url("/path/to/image-1279.webp");
  }
}

// Standard laptops and desktops FULL HD (1280px and up)
@media (min-width: 1280px) {
  .some-element {
    background-image: url("/path/to/image-2048.webp");
  }
}

// You could include more queries if you are targeting
// 2K, 4K, 8K screens, etc.

The code above will allow your site to display responsive background images to varying device sizes while reducing bandwidth for smaller devices. You can even use art direction. For instance, if your desktop layout has the element only needed in 500px wide background, you can set your larger display to only download the smaller size image. It is the img tag equivalent of:

HTML
<img
    src="/path/to/image-767.webp"
    srcset="/path/to/image-768.webp 767w, /path/to/image-1024.webp 1023w, /path/to/image-1280.webp 1279w, /path/to/image-2048.webp 1280w"
    sizes="100vw">

You can even use image-set() in addition to the media queries to target both device sizes as well as devices with higher pixel density/DPI/PPI. Performance analyzers like Lighthouse’s Pagespeed Insights will also thank you for taking the responsive route for background images.

Below is an example:


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *