DEV Community

loading...

Detect AVIF image support to use in your CSS

nucliweb profile image Joan León ・2 min read

AVIF is a next generation image format, in the moment to write this post, the support is only by Chrome 85 and Firefox 77 under a flag.

W3C are working in the CSS Images Module Level 4, and the new module will have an interesting feature, image-set and we'll can define the image type.

.element {
  background-image: image-set( "image.avif" type("image/avif"),
                               "image.webp" type("image/webp"),
                               "image.jpg" type("image/jpeg") );
}
Enter fullscreen mode Exit fullscreen mode

With image-set we'll can define different format and the browser render the first image format supported.

Until we have this awesome feature in the browsers, we can use JavaScript to detect the support, we'll to do a sample with the AVIF format.

The CSS

body {
  background-color: #000;
  background-repeat: no-repeat;
  background-size: cover;
}
body.avif {
  background-image: url(./images/lions.avif);
}
body.no-avif {
  background-image: url(./images/lions.jpg);
}
Enter fullscreen mode Exit fullscreen mode

I know that you can put the image in JPEG format directly in the body and overwrite the background-image if the browser supports it, but for the example I think it's clearer.

The JavaScript

async function supportsAvif() {
  if (!this.createImageBitmap) return false
  const avifData =
    'data:image/avif;base64,AAAAFGZ0eXBhdmlmAAAAAG1pZjEAAACgbWV0YQAAAAAAAAAOcGl0bQAAAAAAAQAAAB5pbG9jAAAAAEQAAAEAAQAAAAEAAAC8AAAAGwAAACNpaW5mAAAAAAABAAAAFWluZmUCAAAAAAEAAGF2MDEAAAAARWlwcnAAAAAoaXBjbwAAABRpc3BlAAAAAAAAAAQAAAAEAAAADGF2MUOBAAAAAAAAFWlwbWEAAAAAAAAAAQABAgECAAAAI21kYXQSAAoIP8R8hAQ0BUAyDWeeUy0JG+QAACANEkA='
  const blob = await fetch(avifData).then((r) => r.blob())
  return createImageBitmap(blob).then(
    () => true,
    () => false
  )
}
;(async () => {
  const classAvif = (await supportsAvif()) ? 'avif' : 'no-avif'
  document.body.classList.add(classAvif)
})()
Enter fullscreen mode Exit fullscreen mode

Demo

Thanks

I want to thank Jon Sneyers and Kornel, true magicians of image coders/decoders, for their help with the option of a base64 of an image of AVIF format as optimized as possible.

Discussion (6)

pic
Editor guide
Collapse
mountainash profile image
Mountain/\Ash

I've combined your code with the older [very similar] webp code from ourcodeworld.com/articles/read/630... to create a version that will work for both AVIF and WebP.

async function supportsEncode() {
  const fallbackclass = 'old';
  if (!this.createImageBitmap) return fallbackclass;

  const avifData =
    'data:image/avif;base64,AAAAFGZ0eXBhdmlmAAAAAG1pZjEAAACgbWV0YQAAAAAAAAAOcGl0bQAAAAAAAQAAAB5pbG9jAAAAAEQAAAEAAQAAAAEAAAC8AAAAGwAAACNpaW5mAAAAAAABAAAAFWluZmUCAAAAAAEAAGF2MDEAAAAARWlwcnAAAAAoaXBjbwAAABRpc3BlAAAAAAAAAAQAAAAEAAAADGF2MUOBAAAAAAAAFWlwbWEAAAAAAAAAAQABAgECAAAAI21kYXQSAAoIP8R8hAQ0BUAyDWeeUy0JG+QAACANEkA=',
    webpData = 'data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoCAAEAAQAcJaQAA3AA/v3AgAA=',
    avifblob = await fetch(avifData).then((r) => r.blob()),
    webpblob = await fetch(webpData).then((r) => r.blob());
  return createImageBitmap(avifblob).then(
    () => 'avif',
    () => {
      return createImageBitmap(webpblob).then(() => 'webp', () => fallbackclass)
    }
  )
};

(async () => {
  const classImg = await supportsEncode();
  document.body.classList.add(classImg);
})()
Enter fullscreen mode Exit fullscreen mode
  • Today in Safari 14.0.2 it returns old in the Tech Preview Safari 14.2 it returns webp
  • In Firefox 85.0.2 is returns webp and in Developer Edition 86.0b9 it returns avif
  • Chrome Version 88.0 returns avif as expected
Collapse
mountainash profile image
Mountain/\Ash

Further to yesterday's comment; I've cleaned this up at codepen.io/mountainash/pen/eYBRpzV (not creating the WebP blob if the AVIF is OK)

Collapse
justinschmitz97 profile image
justinschmitz97

I just compared this to my snippet on avif.io/blog/tutorials/use-avif-in...
Your script is at 900 chars, mine is 600 chars. Is there any benefit I don't see? I'm not criticizing your work, I'm actually curious, cause then I'd implement your version with credits.

Thread Thread
mountainash profile image
Mountain/\Ash

I wasn't aware of your's; it's new to me (and this article and the comments section). Looks good -> use it.

Thread Thread
justinschmitz97 profile image
justinschmitz97

Awesome, thanks for clarifying, I appreciate it. :)

Collapse
wojtekmaj profile image
Wojciech Maj

Update: Firefox 86 now has AVIF support on by default.