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 achieve the same thing in CSS with the image-set()function.

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 my company, 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.