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 ...));">
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).
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);
">
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.
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>
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:
- Generate a unique class name for the background image set
- Add that class to the desired
<div>
(or other element) - 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>
Hope this helped! Feel free to leave a comment if anything is not clear.
Top comments (2)
Hello, I'm coding footer component in react which has background image so I cant use directly tag. Also, even I'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>
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.