DEV Community

Thor Galle
Thor Galle

Posted on • Edited on

2

Use image-set() while supporting Firefox with dynamically loaded background images

You don't need to do anything special anymore 🥳 There is full support for image-set in Firefox since version 89 (released Jun 2021). Go browser standards!

Here's a demo. You'll see it works in Firefox:

The below is an INVALID, old article about a problem that once existed when Firefox didn't support image-set. Only kept for questionable archival purposes. I will probably unpublish this article later.


<div style="
/* fallback */
background-image: url('fallback-img.jpg');
/* responsive */
background-image: -webkit-image-set(url( ... responsive image set ...));">
Enter fullscreen mode Exit fullscreen mode

Solution: put those rules in a <style> tag instead to support fallbacks.

Note: this blog post was a learning from a project at Columbia Road, an updated version can be found on the company site: Tech logs: Use image-set() while supporting Firefox with dynamically loaded background images


Modern browsers widely support the HTML srcset attribute that enables responsive images (MDN, CanIUse). But for its CSS background-image equivalent image-set() (accessible through -webkit-image-set()), there is no support for IE11, Firefox, Firefox for Android and Opera Mini (MDN, CanIUse). (I'm ignoring IE11 overall).

Screen Shot 2020-11-20 at 10.34.32

Support of major browsers for image-set() as of November 20, 2020. Source: CanIUse

Of course you'll want to have a non-responsive fallback image for these non-supporting browsers. Well, that's not as obvious as it sounds.

Problem: using style="" doesn't work

You might be tempted to try the following CSS with a fallback url() expression, that gets overwritten with the -webkit-image-set() expression whenever available.

<div style="
/* provide a fallback for Firefox */
background-image: url('../img/image-2x.jpg');
/* override with a responsive image */
background-image: -webkit-image-set(url('../img/image-1x.jpg') 1x, url('../img/image-2x.jpg') 2x);
">
Enter fullscreen mode Exit fullscreen mode

Unfortunately, if you add the above code to a style="" attribute (as you would often do when you generate responsive background images somewhere), Firefox 84 will complain with this error in the console:

⚠️ Error in parsing value for 'background-image'. Declaration dropped.
Enter fullscreen mode Exit fullscreen mode

How sad. It dropped the whole style attribute value because it could't load the -webkit-image-set(). As a result, it does also not display the fallback.

Solution: use a <style> tag

The following code works however:

<head>
    <style>
        .my-image-id {
            /* provide a fallback for Firefox */
            background-image: url('../img/image-2x.jpg');
            /* override with a responsive image */
            background-image: -webkit-image-set(url('../img/image-1x.jpg') 1x, url('../img/image-2x.jpg') 2x);
        }
    </style>
</head>
<body>
    <!-- this div should have an image background on it -->
    <div class="my-image-id background-box"><div/>
</body>
Enter fullscreen mode Exit fullscreen mode

It seems that a style tag can still be parsed, even though one rule in it is not supported by the browser.

A few things to consider here.

You need a unique class name for each image.

The reason you came here in the first place might have been that you wanted to use the style="" attribute, because you were dynamically adding background images to a template using client-side/server-side image data.

In that use case, you now you need to perform a few intermediate steps:

  1. Generate a unique class name for the background image set
  2. Add that class to the desired <div> (or other element)
  3. Add a CSS rule for that class to a <style> tag somewhere. This could be a new tag in the <head> OR <body>. It should contain the fallback & responsive background-image URLs for that specific images.

For step 1, you could use a GUID generator. In my project however, I used a JS function to generate valid class names from an alphanumeric image ID string that I got from an API.

Tricky to add style rules to the <head>?
You could add them to the <body> too!

If you were previously trying to add the styles to a style tag, it might be tricky to add styles to a <head>, for example, when coding in a restricted server-side template where you can't access the <head>

One solution: it's actually possible to add <style> tags to the <body> as well. This is not a good practice since it's non-standard. But it seems to work in most browsers. I tested this in BrowserStack, and so far only UC Browser on Android seemed to have problems with this technique. Here's an adaptation of the previous example with body style tags:

<!-- this div should have an image background on it -->
<div class="my-image-id background-box"><div/>
<style>
    .my-image-id {
        /* provide a fallback for Firefox */
        background-image: url('../img/image-2x.jpg');
        /* override with a responsive image */
        background-image: -webkit-image-set(url('../img/image-1x.jpg') 1x, url('../img/image-2x.jpg') 2x);
    }
</style>
Enter fullscreen mode Exit fullscreen mode

Hope this helped! Feel free to leave a comment if anything is not clear.

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (2)

Collapse
 
zisanuzum profile image
Zisan-uzum

Hello, I'm coding footer component in react which has background image so I cant use directly tag. Also, even I&#39;m able to use style as object, then webkit doesnt exist. I changed also css file but doesnt work. My code looks like <br> <img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o8tcke7zzpisdhyknjb5.jpg" alt="Image description"></p> <p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qb36ur9mdpom7wpph3rp.jpg" alt="Image description"></p>

Collapse
 
th0rgall profile image
Thor Galle

Hi! Does your background not show up? I can't really understand your problem without a reproduction. Here's a small functioning example, I hope it helps! stackblitz.com/edit/react-ts-fwysu...

It seems Firefox now supports image-set, so this article isn't so relevant anymore. No extra <style> tags necessary. I'll update it.

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more