With Firefox 65 joining the WebP party and thanks to the incredible squoosh app, WebP becomes more than just a lighthouse proposal. So it is time to figure out how to use WebP in every web project.
September 01, 2020: I updated the webp detection script to support avif images too. Read the new blog post about the changes.
Using WebP for <img>
s in your project is possible by using the <picture>
element, explained here which looks like this:
<picture>
<source type="image/webp" srcset="image1x.webp 1x, image2x.webp 2x">
<source type="image/jpeg" srcset="image1x.jpg 1x, image2x.jpg 2x">
<img src="image1x.jpg" alt="describe image content">
</picture>
IE11 does not support picture element magic, so no double resolution images are displayed, but the fallback image.
But that is only half the picture ;-)
WebP progressive enhancement script
To use WebP images as background images, you must check if your browser is capable of WebP images. You can include a modernizr bundle, or search the web and find this feature detection script: https://github.com/vitaliy-bobrov/webp-support, which nearly does what I want.
So I forked this script and changed the way it is working: webp-inline-support. My idea is, to include this script as early as possible in the <head>
, even before your css.
This way, the browser will directly render the page with or without the html.webp
class. In addition my version uses sessionStorage
, to check only one time in a visit for WebP support. Because browser support is growing, I do not use localStorage
. For example: A Firefox user today (27.01.2019) will not see WebP images, but in two days, the same Firefox user is able to see WebP images.
WebP detection script usage
A <head>
will look like this, with my script:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
...
<title>...</title>
<script>!function(e){"use strict";function s(s){if(s){var t=e.documentElement;t.classList?t.classList.add("webp"):t.className+=" webp",window.sessionStorage.setItem("webpSupport",!0)}}!function(e){if(window.sessionStorage&&window.sessionStorage.getItem("webpSupport"))s(!0);else{var t=new Image;t.onload=t.onerror=function(){e(2===t.height)},t.src="data:image/webp;base64,UklGRi4AAABXRUJQVlA4TCEAAAAvAUAAEB8wAiMwAgSSNtse/cXjxyCCmrYNWPwmHRH9jwMA"}}(s)}(document);
</script>
<style>/* inline css */</style>
...
</head>
<body>...
SCSS mixin for WebP background images
I use SCSS and created this mixin to support WebP images (gist):
@mixin bg-url($url, $url2x: false, $webp1x: false, $webp2x: false) {
background-image: url($url);
@if $webp1x {
.webp & {
background-image: url($webp1x);
}
}
@if $url2x {
@media
screen and (-webkit-min-device-pixel-ratio: 2),
screen and (min-resolution: 192dpi),
screen and (min-resolution: 2dppx) {
background-image: url($url2x);
@if $webp2x {
.webp & {
background-image: url($webp2x);
}
}
}
}
}
Hint: The .webp
class increases your css specificity, so remember when you change a background-image or remove it within a @media-query
a simple background-image: none;
will still show your WebP image.
Generating WebP images
If you handle your images manual use Squoosh. I try to automate WebP generation within a gulp and a webpack environment, but my results are still not in production, because sometimes the WebP image is bigger, than its jpeg/png equivalent, or I reduce the quality that much, that it does not look any good.
tbc...
Article Image from Jon Tyson via unsplash and ghost.