How to Detect If Webp Images Are Supported via CSS

How to detect if webp images are supported via CSS

You can use Modernizr. It is a tool that detect
available features on the user's browser. It is just a script to add in your website, and with it, you can write something like that :

.no-webp .home-banner-background {
background-image: url('img/banner.jpg');
}

.webp .home-banner-background {
background-image: url('img/banner.webp');
}

Detecting WebP support

This is my solution - is taking around 6ms and I'm considering WebP is only a feature for a modern browser. Uses a different approach using canvas.toDataUrl() function instead of image as the way to detect the feature:

function support_format_webp()
{
var elem = document.createElement('canvas');

if (!!(elem.getContext && elem.getContext('2d')))
{
// was able or not to get WebP representation
return elem.toDataURL('image/webp').indexOf('data:image/webp') == 0;
}
else
{
// very old browser like IE 8, canvas not supported
return false;
}
}

Cross-browser Webp images support

You need to fallback to a supported image format.

Below's example is using the <picture> element and the <source> elements with an img element fallback. The browser will try loading the assets inside the <picture> element from top to bottom until all the "conditions were satisfied" (optional sizes attribute and complex srcset which aren't in the below code) and the content format is supported.

<picture>
<source srcset="image.webp" type="image/webp">
<source srcset="image.jpg" type="image/jpeg">
<img src="image.jpg" alt="">
</picture>


If the images are used in CSS:

You can use Modernizr's .no-webp class name to target non-support browsers and serve a non-webp format instead:

.no-webp .elementWithBackgroundImage {
background-image: url("image.jpg");
}

This article has good information you can use



Detecting browser WEBP support - A guide by Google (creator of WEBP)

Dealing with Safari and .webp images in 2022

Yes, it's hard to provide fallbacks for CSS background-images

In my question I wrote:

If I were using marked-up images, declaring one or more fallback images is elementary [...]

But (sigh) in this instance, the images are CSS background-images, so options for creating fallbacks are more limited

And for now, at least, - ie. while we're still waiting (in 2022) for widespread cross-browser support for the CSS image-set() function - that's true.



But a marked-up <img> can replace each CSS background-image

While I was hunting around for alternative approaches, I unexpectedly came across this July 2021 comment by Quentin Albert:

For what most people use background images for you can nowadays easily use object-fit + object-position.

Source: https://css-tricks.com/using-performant-next-gen-images-in-css-with-image-set/

This was news to me. I was dimly aware of the object-fit CSS property, but I'd never come across the object-position CSS property at all.

But it absolutely works!!



The CSS I would have used if image-set() had support

If image-set() had extensive cross-browser support, this was my intended CSS, which would enable a fallback image for Safari:

.my-image-1 {
background-image: url(image-set('my-sprited-images.webp', 'my-sprited-images.png'));
background-position: 0, 0;
}

.my-image-2 {
background-image: url(image-set('my-sprited-images.webp', 'my-sprited-images.png'));
background-position: -100px, 0;
}


The HTML + CSS I can use instead (thanks to object-position)

Since the above isn't close to reliable, I can declare the fallback image in HTML instead and position it using object-position:

HTML:

<picture>
<source srcset="my-sprited-images.webp" type="image/webp">
<source srcset="my-sprited-images.png" type="image/png">
<img class="my-image-1" src="/my-sprited-images.png" alt="My Image 1">
</picture>

<picture>
<source srcset="my-sprited-images.webp" type="image/webp">
<source srcset="my-sprited-images.png" type="image/png">
<img class="my-image-2" src="/my-sprited-images.png" alt="My Image 2">
</picture>

CSS:

.my-image-1 {
object-position: 0 0;
}

.my-image-2 {
object-position: -100px 0;
}

How to load a webp image for a background-img when the browser allows it and when not load a png?

You can check for the browser using the method explained here. From there, you could check for the browsers that have it or not and add the relevant class to the HTML element in question.

So you would have a different class for each background image. For example:

.webp-supported {
background-image: url(/coe/julio-rodriguez/proyecto/public/img/webp/hero-banner.webp);
}

.webp-not-supported {
background-image: url(/coe/julio-rodriguez/proyecto/public/img/webp/hero-banner.png);
}

Use WebP images on website

You must use modernizr to detect whether browser support webp or not and then apply appropriate style to it

.no-webp .mybackgroundimage 
{
background: url('image.jpg') no-repeat;

}

.webp .mybackgroundimage
{
background: url('image.webp') no-repeat;

}

How to use WebP in sass

There's no way to detect webp support with CSS.

The best you are likely to be able to achieve is to use JavaScript to detect support and add a class to an element (e.g. with modernizr). Since the body element is usually outside the scope of the elements modified by React, adding the class there with modernizr shouldn't be a problem.

Then you can use that class to pick which rule to use:

.banner{
background-image: url("/images/image.jpg");
}

.webp .banner{
background-image: url("/images/image.webp");
}


Related Topics



Leave a reply



Submit