How to Use Webp Images and Support Safari

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;
}

WebP images doesn't display in safari although added polyfill

I custom built modernizr just took WebP checker from it and then used this approches:

for HTML image:

<picture>
<source srcset="img/awesomeWebPImage.webp" type="image/webp">
<source srcset="img/creakyOldJPEG.jpg" type="image/jpeg">
<img src="img/creakyOldJPEG.jpg" alt="Alt Text!">
</picture>

for CSS image:

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

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

for passing image link as props (within Vue2 application or any other front-end framework):

document.querySelector("html").classList[0] === 'webp' ? this.webpEnabled = true : this.webpEnabled = false;
this.webpEnabled ? this.currentImages = this.imagesWebp : this.currentImages = this.imagesJpeg

<some-component :image="currentImages[0]"></some-component>

WEBP support for legacy browsers using picture

If you want to show webp image in Chrome and png image in IE11, you need to put the webp source at first. You can refer to the following code, it shows rose (png image) in IE 11 and tree (webp image) in Chrome:

<picture>
<source type="image/webp" srcset="https://www.gstatic.com/webp/gallery/4.sm.webp">
<source type="image/png" srcset="https://www.gstatic.com/webp/gallery3/1.sm.png">
<img src="https://www.gstatic.com/webp/gallery3/1.sm.png">
</picture>

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)

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');
}


Related Topics



Leave a reply



Submit