CSS image-set() for Responsive Raster Graphics
The CSS image-set() function provides a native way to
deliver responsive raster graphics via CSS properties such as
background-image. Much like the HTML srcset
attribute on the <img> element,
image-set() allows developers to supply a list of image
sources paired with resolution and format conditions, enabling the
browser to automatically select and download the optimal asset based on
a user's display capabilities and network conditions. This article
explains how image-set() works, how it manages device pixel
density and modern image formats, and how to implement it cleanly.
Resolution Switching for High-DPI Displays
Serving high-resolution (Retina/high-DPI) background images
historically required complex media queries relying on
min-resolution or vendor-prefixed device pixel ratios. The
image-set() function streamlines this by accepting
resolution descriptors such as 1x, 2x, or
specific dpi values directly inside the property
declaration.
.hero-banner {
background-image: image-set(
url("hero-standard.jpg") 1x,
url("hero-retina.jpg") 2x
);
}When evaluating this rule, a standard display (1x) downloads the smaller file, saving bandwidth and reducing load times. A high-density screen (2x or higher) downloads the sharper asset to prevent visual blurring. The browser handles this decision internally, eliminating the need for duplicated CSS rules and media query blocks.
Format Negotiation with
type()
Modern specifications of image-set() allow format-based
content negotiation using the type() function. This enables
developers to serve modern raster formats like AVIF and WebP without
relying on JavaScript or server-side user-agent sniffing.
.card-header {
background-image: image-set(
url("photo.avif") type("image/avif"),
url("photo.webp") type("image/webp"),
url("photo.jpg") type("image/jpeg")
);
}The browser evaluates the sources from top to bottom and downloads the first format it supports. Format detection can also be combined with resolution descriptors to deliver the most efficient file for any given scenario:
.avatar {
background-image: image-set(
url("avatar-2x.avif") type("image/avif") 2x,
url("avatar-1x.avif") type("image/avif") 1x,
url("avatar-2x.jpg") type("image/jpeg") 2x,
url("avatar-1x.jpg") type("image/jpeg") 1x
);
}Fallbacks and Compatibility
Modern browsers fully support the standardized
image-set() syntax. However, to guarantee compatibility
with older legacy browsers that do not recognize the function, always
supply a standard background-image fallback declaration
before the image-set() property:
.thumbnail {
background-image: url("fallback.jpg");
background-image: image-set(
url("optimized.webp") type("image/webp") 1x,
url("optimized@2x.webp") type("image/webp") 2x,
url("fallback.jpg") type("image/jpeg") 1x,
url("fallback@2x.jpg") type("image/jpeg") 2x
);
}By decoupling image resolution selection from layout logic,
image-set() keeps stylesheets concise, conserves user data,
and ensures raster graphics remain crisp across various screen densities
and browser environments.