AVIF Fallback Syntax in CSS image-set

This article explains how to implement AVIF images using the CSS image-set() function while maintaining full backward compatibility. By combining CSS cascading fallbacks with the type() function inside image-set(), developers can serve next-generation AVIF images to modern browsers while gracefully falling back to WebP or standard JPEG and PNG formats in legacy environments.


To reliably use AVIF with fallbacks, you must use a two-tiered fallback approach: the standard CSS cascade for browsers lacking modern image-set() support, and format-negotiated types inside image-set() for modern engines.

.responsive-background {
  /* Tier 1: Fallback for browsers with no image-set() or type() support */
  background-image: url("image.jpg");

  /* Tier 2: Modern format negotiation using image-set() */
  background-image: image-set(
    url("image.avif") type("image/avif") 1x,
    url("image@2x.avif") type("image/avif") 2x,
    url("image.webp") type("image/webp") 1x,
    url("image@2x.webp") type("image/webp") 2x,
    url("image.jpg") type("image/jpeg") 1x,
    url("image@2x.jpg") type("image/jpeg") 2x
  );
}

How the Fallback Mechanism Works

  1. The Cascade Fallback:
    Browsers parse CSS sequentially. Older browsers that do not understand image-set() or fail to parse the type() syntax will ignore the second background-image declaration and render the standard url("image.jpg").

  2. The type() Function:
    CSS Images Module Level 4 introduces the type() functional notation within image-set(). When a browser encounters an entry with an unsupported MIME type (such as type("image/avif") on an older engine), it skips that option and moves to the next supported format, such as type("image/webp") or type("image/jpeg").

  3. Ordering Matters:
    Place the most optimized format first (AVIF), followed by secondary next-generation formats (WebP), and end with universally supported formats (JPEG or PNG).

Handling Vendor Prefixes for Legacy WebKit

Older versions of Safari and Chromium-based browsers supported an earlier draft of image-set() using -webkit-image-set(), but lacked support for the type() function. If you need to support these legacy browser versions, avoid using type() inside the prefixed property and rely strictly on resolution switching for JPEG/PNG:

.responsive-background {
  background-image: url("image.jpg");
  background-image: -webkit-image-set(
    url("image.jpg") 1x,
    url("image@2x.jpg") 2x
  );
  background-image: image-set(
    url("image.avif") type("image/avif") 1x,
    url("image.webp") type("image/webp") 1x,
    url("image.jpg") type("image/jpeg") 1x
  );
}