CSS image-set() With type(): Which Background File Chrome Downloads
image-set() with AVIF listed first made Chrome 155 download a 24.2 KB AVIF instead of the 54.1 KB JPEG, with a single request, even when a plain url() fallback was declared first.
For an <img>, the <picture> element chooses between AVIF, WebP and JPEG. CSS background images have their own tool for the same job: image-set(), which can list files by format with type() and by screen density with 1x, 2x and 3x. Which file does Chrome download for each kind of image-set(), and does a plain url() fallback cause a second download? We tested five declarations on screens at three densities.
The test
Each page holds one 400 × 267-pixel element with a background image of a CC0 market photo, prepared at 400, 800 and 1200 pixels in JPEG (MozJPEG quality 80), WebP (quality 75) and AVIF (quality 50). The five declarations were: image-set() with type('image/avif'), type('image/webp') and type('image/jpeg'); density versions at 1x and 2x; density versions at 1x, 2x and 3x; a list whose first entry is marked type('image/jxl'); and a plain background-image: url(…jpg) declared first, followed by an image-set() with AVIF and JPEG. That last pattern is the usual way to support browsers without image-set().
Each page was loaded in Chrome 155.0.8059.82 at device pixel ratios of 1, 2 and 3, with the cache disabled, and the requests were read from the DevTools Protocol. Byte figures are transfer sizes, including about 180 bytes of HTTP headers. See the methodology.
A first run of this test returned no request at all for the type() cases. The cause was in our test page, not in Chrome: we had written the type strings in double quotes inside a style attribute that was itself delimited by double quotes, which broke the declaration. The results below come from the corrected pages.
Results

| CSS | 1× screen | 2× screen | 3× screen | Max requests |
|---|---|---|---|---|
| type(): AVIF, WebP, JPEG | 800.avif (24.2 KB) | 800.avif (24.2 KB) | 800.avif (24.2 KB) | 1 |
| 1x and 2x | 400.jpg (18.8 KB) | 800.jpg (54.1 KB) | 800.jpg (54.1 KB) | 1 |
| 1x, 2x and 3x | 400.jpg (18.8 KB) | 800.jpg (54.1 KB) | 1200.jpg (95.8 KB) | 1 |
| type(‘image/jxl’) listed first | 800.jpg (54.1 KB) | 800.jpg (54.1 KB) | 800.jpg (54.1 KB) | 1 |
| url() fallback, then image-set() | 800.avif (24.2 KB) | 800.avif (24.2 KB) | 800.avif (24.2 KB) | 1 |
type() worked like <picture>. With AVIF listed first, Chrome downloaded only the 24.2 KB AVIF at every density. The 54.1 KB JPEG listed last was never requested.
The url() fallback cost nothing. When a plain JPEG background was declared first and the image-set() second, Chrome used the later declaration and downloaded only the AVIF. Because the second declaration replaces the first before any image is requested, the JPEG was never fetched.
Density descriptors chose by pixel ratio, up to the largest entry. The 1x/2x set delivered the 400-pixel file on a 1× screen and the 800-pixel file on 2× and 3× screens. Adding a 3x entry made the 3× screen download the 1200-pixel file (95.8 KB) instead of the 800-pixel one (54.1 KB).
Chrome 155 accepted type('image/jxl'). The first entry, which we had marked as JPEG XL but which pointed to a JPEG file, was selected and displayed at all three densities. That matches what we saw in our picture element test and in Chrome’s Accept header.
How to use image-set()
- Write the plain
url()first and theimage-set()second. Browsers that understandimage-set()override the fallback without downloading it; older ones keep the fallback. - List AVIF before WebP and JPEG. Chrome takes the first type it supports, exactly as with
<picture>sources. - Use density entries for backgrounds of fixed size, such as icons and small decorative images. For full-width hero images, density alone does not adapt to the window width; a media query or an
<img>withsrcsetandsizesis the better tool, as our responsive background images test shows. - Quote type strings carefully in inline styles. Our own first attempt failed silently because of quotes.
Practical conclusion
In Chrome 155, image-set() with type() delivered the AVIF background (24.2 KB instead of 54.1 KB for the JPEG) with a single request, even when a plain url() fallback came first. Use it for CSS backgrounds with the fallback first and AVIF at the top of the list.
Limitations
Chrome only; browsers without type() support were not tested. One photo and one element size. Device pixel ratios were emulated by Chrome.
Data and files
Download image-set.csv (15 rows, 0.7 KB) · Method: testing methodology. Photo: image credits.


