Fallback Background Images loads in Firefox

1.2k Views Asked by At

I have been working on my websites page speed improvement. I planned to use AVIF format images. This image format is supported only in the latest Chrome browser versions. In order to provide a fallback image, I have used this CSS:

.banner-bg {
  background-image: url('https://cdn.xyz.com/content/images/desktop_banner_bg.jpg'), linear-gradient(90deg, rgb(246, 250, 255) 0%, rgb(244, 249, 255) 33%, rgb(213, 227, 255) 70%, rgb(211, 225, 255) 100%);
}

.banner-bg{
  background: url('https://cdn.xyz.com/content/images/desktop_banner_bg-updated.avif'), linear-gradient(90deg, rgb(246, 250, 255) 0%, rgb(244, 249, 255) 33%, rgb(213, 227, 255) 70%, rgb(211, 225, 255) 100%);
}

This works fine in Chrome, where only the AVIF bg image is loaded and the jpg format is ignored. In older versions of Chrome, the AVIF format is ignored, and the jpg format is loaded.

Only one image is loaded in the page. Whereas in Firefox and other browsers, AVIF format is ignored and jpg is not loaded. I tried using the code below, which works, but both the format images are loaded in the page, which increases my page size.

.banner-bg {
  background-image: url('https://cdn.xyz.com/content/images/desktop_banner_bg.jpg'), url('https://cdn.xyz.com/content/images/desktop_banner_bg-updated.avif'), linear-gradient(90deg, rgb(246, 250, 255) 0%, rgb(244, 249, 255) 33%, rgb(213, 227, 255) 70%, rgb(211, 225, 255) 100%);
}

Is there a way to provide a fallback background image in Firefox, which loads only when the default background image is ignored?

3

There are 3 best solutions below

3
On

Hi use this code in your css element where you want the bg + fallbackbg:

bg {
background-image: url(/images/top-landing-home-cropped.jpg);
background-image: -webkit-image-set(url(/images/top-landing-home-cropped.webp)1x );
}

The browser will try to load the WEBP and if it's not avail. or there is an error code it will load the JPG.

For an <img> element, you can use this 'hack' that works 100% tested on my sites all common browsers as of 14.10.2020:

<img alt="" src="/images/xx.webp" onerror="this.onerror=null; this.src='/images/xx.png'">

Any questions just comment please thanks

0
On

Usually an fallback works like this:

<picture>
  <source srcset="img/Image.avif" type="image/avif">
  <img src="img/image.jpg" alt="Alt Text!" type="image/jpg">
</picture>

However if you want do to it with background-image you can try to use a combination with @supports

.banner-bg{
  background: url('https://cdn.xyz.com/content/images/desktop_banner_bg-updated.jpg'), linear-gradient(90deg, rgb(246, 250, 255) 0%, rgb(244, 249, 255) 33%, rgb(213, 227, 255) 70%, rgb(211, 225, 255) 100%);

  @supports(content-visibility: auto) {
    background: url('https://cdn.xyz.com/content/images/desktop_banner_bg-updated.avif'), linear-gradient(90deg, rgb(246, 250, 255) 0%, rgb(244, 249, 255) 33%, rgb(213, 227, 255) 70%, rgb(211, 225, 255) 100%);
  }
}

Since content-visibility has also very low browser support you can check if the browser has it and if yes you load the avif image.

Note here: Its not guaranteed that if you load the avif that it will be displayed.

https://caniuse.com/?search=avif

https://caniuse.com/?search=content-visibility

They have similar browser support

Also some very old browsers dont support @supports. I reccommend to use <picture> approach

0
On

Based on the information provided by caniuse Chrome versions 85 and up support the avif format. With that in mind, you could implement a rudimentary Browser detection using JavaScript, and dynamically add a class that makes reference to the desired file format:

HTML

<body>
  <div class="banner"></div>
  <script src="https://unpkg.com/[email protected]/es5.js"></script>
  <script>

    // Get the banner
    const banner = document.querySelector('.banner');

    // Initialize bowser and get the results
    const  { parsedResult } = bowser.getParser(window.navigator.userAgent);

    // Isolate the browser
    const { browser } = parsedResult;

    // Get the version number and name for Chrome
    const verNumber = Number(browser.version.split('.')[0]);
    const browserName = browser.name;

    // Conditionally load backgrounds
    if (browserName == 'Chrome' && verNumber >= 85) {
      banner.classList.add('banner-bg-avif');
    } else {
      banner.classList.add('banner-bg-jpg');
    }
  </script>
</body>

CSS

.banner {
  height: 400px;
}

.banner-bg-jpg {
  background-size: cover;
  background-image: url('photo.jpg'), linear-gradient(90deg, rgb(246, 250, 255) 0%, rgb(244, 249, 255) 33%, rgb(213, 227, 255) 70%, rgb(211, 225, 255) 100%);
}

.banner-bg-avif {
  background-size: cover;
  background-image: url('photo.avif'), linear-gradient(90deg, rgb(246, 250, 255) 0%, rgb(244, 249, 255) 33%, rgb(213, 227, 255) 70%, rgb(211, 225, 255) 100%);
}

Note: The general consensus seems to be that that native user agent detection is somewhat unreliable, that's why the example code leverages Bowser to improve Browser detection.