Fully support AVIF in your CSS today.

01.10.20 · 0 min read

    Table of Content


Using AVIF images via HTML is very easy, as you can read . 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 it 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!)-->

The Script

To avoid visible image changes when adding the avif/webp class to your DOM, add the 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) };
3var avif = new Image();
6avif.onload = function () { AddClass("avif") };
8avif.onerror = function () {
9  var webp = new Image();
10  webp.src = "data:image/webp;base64,UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==";
11  webp.onload = function () { AddClass("webp") }
Minified version (600 Bytes):
1function F(a){document.documentElement.classList.add(a)}var A=new Image;A.src="data:image/avif;base64,AAAAFGZ0eXBhdmlmAAAAAG1pZjEAAACgbWV0YQAAAAAAAAAOcGl0bQAAAAAAAQAAAB5pbG9jAAAAAEQAAAEAAQAAAAEAAAC8AAAAGwAAACNpaW5mAAAAAAABAAAAFWluZmUCAAAAAAEAAGF2MDEAAAAARWlwcnAAAAAoaXBjbwAAABRpc3BlAAAAAAAAAAQAAAAEAAAADGF2MUOBAAAAAAAAFWlwbWEAAAAAAAAAAQABAgECAAAAI21kYXQSAAoIP8R8hAQ0BUAyDWeeUy0JG+QAACANEkA=",A.onload=function(){F("avif")},A.onerror=function(){var a=new Image;a.src="data:image/webp;base64,UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==",a.onload=function(){F("webp")}};
Minified version without WebP detection (400 Bytes):


Once implemented, we can simply use the following CSS due to the high level classes.
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') }
7/* Add Support for high Pixel Ratio Devices (Retina) */
9    screen and (min-resolution: 2dppx),
10    screen and (-webkit-min-device-pixel-ratio: 2),
11    screen and (min-resolution: 192dpi) {
12    .img { background-image: url('avif-in-css@2x.jpg') }
13    .webp .img { background-image: url('avif-in-css@2x.webp') }
14    .avif .img { background-image: url('avif-in-css@2x.avif') }

The outcome (05.01.21)

Using this script leads to the following screenshots. Back in the day, Firefox Quantum didn't 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

posted a f*king amazing SCSS background mixin that you can use as well 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  }

Look into the future

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 allows us to specify different image formats. The browser renders the first image format supported by the browser. The following example shows how the type() can be used to deliver multiple images in high-quality formats and older formats that are more widely used. Note that the AVIF is shown first, as both images have the same resolution. JPEG, which comes second, is automatically deleted in user agents that support AVIF images. Older user agents, however, ignore AVIF images because they know they do not support image / avif files, and instead select JPEG images.
2	image-set(
3		"zebra.avif" type("image/avif"),
4		"zebra.webp" type("image/webp"),
5		"zebra.png" type("image/png")
6	);
Currently, image-set is supported by 90% of browsers, but does 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 is child's play. Simply 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.