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") );
}
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);
}
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)
})()
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.
Top comments (10)
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.
old
in the Tech Preview Safari 14.2 it returnswebp
webp
and in Developer Edition 86.0b9 it returnsavif
avif
as expectedChrome Version 112.0.5615.121 (Official Build) (x86_64) returns
webp
which is not right.Ensure you checkout the updated codepen code which was added to the comments 2yrs ago. It's returning correctly for the latest version of Chrome (aka, the version you've listed).
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)
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.
I wasn't aware of your's; it's new to me (and this article and the comments section). Looks good -> use it.
Awesome, thanks for clarifying, I appreciate it. :)
Who googled this topic I have an alternate sync version for you, so you don't need to wait till onload or make some promises:
thanks))
p.s.: check this before simple copy it caniuse.com/avif maybe something has updated
UserAgent lookups to define feature support should be a last resort - it's always better to test for the feature - you never know when a new browser will come out and make the test cases fail leaving the user with a suboptimal experience.
Update: Firefox 86 now has AVIF support on by default.