Use AVIF images as CSS Background

0 min reading time

Introduction

Using AVIF images via HTML is very easy as you can read in this tutorial. Furthermore, it is easy because HTML provides a media-type hint that helps the browser deliver the best version of your image. Unfortunately, CSS does not have such an option. However, with a simple Javascript function, we can easily support WebP and AVIF. We have created a detection script that manipulates the HTML element of your page by writing classes.

How CSS works

We must remember that in CSS, the first rule does not win, but the last rule wins. We have created a script that checks AVIF and WebP support by loading an AVIF-encoded 1x1 pixel image. If the browser successfully loads the AVIF image, the HTML element receives an "avif" class.
If the browser does not load the AVIF image, the script will further check the browser's support for WebP using the method described above. If your browser successfully loads the image, the HTML element gets a "webp" class. Of course, this function is optional, and you can remove it according to your preferences.
If it is very unlikely that your browser will not pass this test, the HTML element will not get any class at all.

1<html></html> <!-- no class at all, you have to use jpg (oh god)-->
2<html class="webp"></html> <!-- you can use webp-->
3<html class="avif"></html> <!-- you can use avif (heck yeah!)-->

AVIF support detection script

To avoid visible image changes when adding the avif/webp class to your DOM, add the following content as an inline script in your header above any CSS content. The minified version of this script is a tiny 600-byte-piece and takes 5ms to load, which is perfectly fine for the benefit it provides.

1function AddClass(class) { document.documentElement.classList.add(class) };
2var avif = new Image();
3avif.src = "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=";
4avif.onload = function () { AddClass("avif") };
5avif.onerror = function () {
6  var webp = new Image();
7  webp.src = "data:image/webp;base64,UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==";
8  webp.onload = function () { AddClass("webp") }
9}

Minified version (600 Bytes):

1function F(a){document.documentElement.classList.add(a)}var A=new Image;A.src="data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=",A.onload=function(){F("avif")},A.onerror=function(){var a=new Image;a.src="data:image/webp;base64,UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==",a.onload=function(){F("webp")}};

Code Snippet

Once implemented, we can use the following CSS due to the high-level classes and cascading.

1/* Simple approach */
2.img { background-image: url('avif-in-css.jpg') }
3.webp .img { background-image: url('avif-in-css.webp') }
4.avif .img { background-image: url('avif-in-css.avif') }
5/* Add Support for high Pixel Ratio Devices (Retina) */
6@media
7    screen and (min-resolution: 2dppx),
8    screen and (-webkit-min-device-pixel-ratio: 2),
9    screen and (min-resolution: 192dpi) {
10    .img { background-image: url('avif-in-css@2x.jpg') }
11    .webp .img { background-image: url('avif-in-css@2x.webp') }
12    .avif .img { background-image: url('avif-in-css@2x.avif') }
13}

Using this script leads to the following screenshots. Back in the day, Firefox Quantum did not support WebP or AVIF, so there is no class. Chrome currently supports AVIF, so AVIF is displayed. Edge does not support AVIF and supports WebP, so our site has a webp class.

firefox quantum without any classour website on chrome gets an avif classmicrosoft edge with a webp class in the html element

SCSS background mixin

Earlier this week, Raoul Kramer posted an amazing SCSS background mixin that can be used to support AVIF and WebP.

1@mixin bg-url($url, $url2x: false, $webp1x: false, $webp2x: false, $avif1x: false, $avif2x: false) {
2  background-image: url($url);
3  @if $webp1x { .webp & { background-image: url($webp1x) }}
4  @if $avif1x { .avif & { background-image: url($avif1x) }}
5  @if $url2x {
6    @media
7    screen and (-webkit-min-device-pixel-ratio: 2),
8    screen and (min-resolution: 192dpi),
9    screen and (min-resolution: 2dppx) {
10      background-image: url($url2x);
11      @if $webp2x {.webp & {background-image: url($webp2x)}}
12      @if $avif2x {.avif & {background-image: url($avif2x)}}
13    }
14  }
15}

Future implementation

The World Wide Web Consortium (W3C) is developing the CSS Images Module Level 4, which allows us to define the image type. The image-set property will enable us to specify different image formats. The browser renders the first image format supported by the browser.
The following example shows how type() can deliver multiple images in high-quality and older formats that are more widely used. Note that the AVIF is shown first, as both pictures have the same resolution. JPEG, which comes second, is automatically deleted in user agents that support AVIF images.
However, older user agents ignore AVIF images because they know they do not support image / avif files and instead select JPEG images.

1background-image:
2  image-set(
3    "zebra.avif" type("image/avif"),
4    "zebra.webp" type("image/webp"),
5    "zebra.png" type("image/png")
6  );

Currently, 90% of browsers support image-set but do not yet support type declaration. This is a brand-new feature for CSS4. Until browsers support this feature, we must use JavaScript to detect AVIF and WebP support.

Generating AVIF images

Creating AVIF files with avif.io is child's play. Drag the files into the converter, and it will do the rest. You will get the best results in the shortest time.

Profit from a faster website, higher ranking and better conversions.
Convert your images to AVIF for free.