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
Bootstrap Full-Width Text-Input Within Inline-Form
Jenkins Content Security Policy
Load External CSS File in Body Tag
Images in Github Pages and Relative Links
How to Center-Justify The Last Line of Text in CSS
Twitter Bootstrap: Center Pills
Content Security Policy: "Img-Src 'self' Data:"
What Is a Non-Replaced Inline Element
How Is HTML5 Webstorage Data Physically Stored
Get Parameters in The Url with Codeigniter
How to Vertical Center Text Next to an Image in HTML/CSS
How to Remove The Dotted Line Around The Clicked a Element in HTML
How to Specify Model to a Nginclude Directive in Angularjs
How to Set Favicon.Ico Properly on Vue.Js Webpack Project
How to Get a Textarea to Stretch to Fit Its Content Without Using PHP or JavaScript
Make Tbody Scrollable in Webkit Browsers
Table with Table-Layout: Fixed; and How to Make One Column Wider