Optimizing images with the CSS image-set() function

I previously blogged about optimizing images with the HTML <picture> tag. Tl;dr the <picture> tag lets you specify multiple sources for an image, and the browser will load the first one that it supports.

You can use the image-set() function to get equivalent behavior in CSS.

Short example:

<div class="bg-image"></div>
<style>
.bg-image {
    background-image: url("./image.png");
    /* Vendor prefix for chromium browsers */
    background-image: -webkit-image-set(url("./image.avif") type("image/avif"), url("./image.webp") type("image/webp"));
    background-image: image-set(url("./image.avif") type("image/avif"), url("./image.webp") type("image/webp"));
}
</style>

Supporting browsers will choose the first image format they support, and use it as the background-image.

You can inspect the image above to see the image-set function in action.

Browser support for image-set() is relatively poor, and Chromium browsers currently require the -webkit- prefix. To make sure your images work everywhere, you need a separate declaration, in this example a background-image: url("...") without an image-set().

But it's worth it for the browsers that do support it! At InsiderPie, we managed to reduce the combined image size on a page with lots of images by more than 97% in Firefox, by using AVIF instead of PNG.