The html <picture>
element has had the ability to use fallback image file types since it's inception. The type()
function in image-set()
adds this ability to CSS image declarations (background-image
, border-image
, mask-image
, etc).
Syntax with with fallback
background-image: url("images/test.jpeg");
background-image:
image-set(
"images/test.avif" type("image/avif"),
"images/test.webp" type("image/webp"),
"images/test.jpeg" type("image/jpeg")
);
Assuming the above example code in a browser with image-set()
and type()
support the browser will first check for AVIF support. If not supported the browser will skip this option and move on to check for WEBP support etc. Once the browser finds a supported file type it will begin the process of using that file. The browser will not download images with unsupported mime types.
If image-set()
with type()
is not supported the entire image-set()
declaration will be ignored and the browser will fallback to:
background-image: url("images/test.jpeg");
Like the url()
function image-set()
(if supported) will never fallback. You can think of image-set()
with type()
as is a more flexible dead end than url()
.
Combining type() and resolution
background-image:
image-set(
"foo.jpg",
"foo-2x.avif" 2x type("image/avif"),
"foo-2x.jpg" 2x
);
You may want to take advantage of a file type with better compression for devices with high resolutions. In the above example a 2x device would be served an AVIF if the browser supports it and fall back to a JPG if not.
@supports
@supports not (background: image-set("foo.png" type("image/png")) ){
.notwebp .contain{
background-image: url('test.jpg');
}
.webp.notavif .contain{
background-image: url('test.webp');
}
.avif .contain{
background-image: url('test.avif')
}
}
@supports (background: image-set("foo.png" type("image/png")) ){
.contain{
background-image: image-set(
"test.avif" type("image/avif"),
"test.webp" type("image/webp"),
"test.jpg" type("image/jpg")
);
}
}
If you are already using a Modernizer like script to add mime type support information to your html
tag through classes the above @supports
example can be used to check for image-set()
and type()
support so it can be used as a replacement if available.
Browser Support
Support only in Firefox 89 (as of writing - 5/2021). If you want this implemented in Chrome star this bug: https://bugs.chromium.org/p/chromium/issues/detail?id=630597&can=2&q=css%20image-set
Links
W3C Spec: https://drafts.csswg.org/css-images-4/#image-set-notation
MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/image-set()#using_image-set_to_provide_alternative_formats
Chrome: https://bugs.chromium.org/p/chromium/issues/detail?id=630597&can=2&q=css%20image-set
Developer tools support in Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=1687033
Top comments (0)