DEV Community

jsnkuhn
jsnkuhn

Posted on • Updated on

Notes on CSS image-set() with type()

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")
  );
Enter fullscreen mode Exit fullscreen mode

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
  );
Enter fullscreen mode Exit fullscreen mode

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")
        );
    }
}
Enter fullscreen mode Exit fullscreen mode

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

Discussion (0)