Is there a srcset equivalent for css background image

img with srcset attribute looks like a great way of doing responsive images. Is there an equivalent syntax that works in css background-image property?

HTML

<img src="small.jpg" srcset="medium.jpg 1000w, large.jpg 2000w" alt="yah">

CSS

.mycontainer { background: url('what goes here?');
}

10 Answers

image-set is the equivalent CSS feature. We should add equivalent srcset functionality (defining resources according to their dimensions) to the spec.

Currently implemented in all major Browsers (Firefox, Chrome, Safari, Edge) with the -webkit- prefix. Safari only supports supports the x descriptors.

4

Another approach, which is quite frankly more robust, would be to adapt the characteristics and options of background images to an image with the srcset attribute.

To do this, set the image to be width: 100%; height: 100%; and object-fit: cover or contain.

Here is an example:

.pseudo-background-img-container { position: relative; width:400px; height: 200px;
}
.pseudo-background-img { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover;
}
<div>
<img src="" srcset=" 640w, 280w, 432w, 216w" sizes="(max-width: 640px) 100vw, 640px">
</div>

This may not be the best approach for everyone but I imagine it will get most the desired results without any javascript workaround.

2

Pretty sure that:

background: -webkit-image-set( url('path/to/image') 1x, url('path/to/high-res-image') 2x );

works the same way. The browser will examine the images, see which fits best and will use that one.

4

You can use media queries for your purpose. It's easy as this:

.mycontainer { background-image:url("img/image-big.jpg"); // big image
}
@media(max-width: 768px){ .mycontainer { background-image:url("img/image-sm.jpg"); // small image }
}

And I think it works on every browser who support media queries ;)

3

For a polyfill, you can use an img with srcset as a mechanism for downloading the correct image size, then use JS to hide it and set the background-image of a parent element.

Here's a fiddle:

The use of onload and putting the JS as a blocking script in the <head> is important. If you put the script later (say at the end of <body>), you can get a race condition where img.currentSrc hasn't been set yet by the browser. It's best to wait for it to be loaded.

The example allows you to see the original img being downloaded. You can easily hide it with some CSS.

1

Similar solution using <picture> element:Tutorial here

Tutorial's case:

I’m doubtful that if I use the same image for a smaller screen size, the primary subject of my image may become too small in size. I want to display a different image (more focused on the primary subject) in a different screen size, but I still want to display separate assets of the same image based on device-pixel ratio, and I want to customize height and width of the image based on viewport.

Example code:

<picture>
<source media="(max-width: 20em)" srcset="images/small/space-needle.jpg 1x,
images/small/space-needle-2x.jpg 2x, images/small/space-needle-hd.jpg 3x">
<source media="(max-width: 40em)" srcset="images/medium/space-needle.jpg 1x,
images/medium/space-needle-2x.jpg 2x, images/medium/space-needle-hd.jpg 3x">
<img src="space-needle.jpg" alt="Space Needle">
</picture>
3

If you are using Foundation framework (), you can use Interchange plugin for that:

<div>
</div>
1

According to CSSTricks, image-set() should be used for this purpose as of 2021.

Here's the full snippet that it recommends using for support of all modern browser versions:

.hero { /* Fallback */ background-image: url("platypus.png"); /* Chrome/Edge/Opera/Samsung, Safari will fallback to this as well */ background-image: -webkit-image-set(url("platypus.png") 1x, url("platypus-2x.png") 2x); /* Standard use */ background-image: image-set("platypus.png" 1x, "platypus-2x.png" 2x);
}

Based on @Weston's answer, I've built a more general jQuery solution, you can basically just copy&paste the JS and CSS and focus on the HTML part ;)

TL;DR - fiddle:

CSS

...to ensure images will be hardly visible while loading

.srcSet{ position: fixed; z-index: 0; z-index: -1; z-index: -100; /* you could probably also add visibility: hidden; */
}

JS / jQuery

This script will go through all images that have srcSet class and bind load event that takes currentSrc (or src if not supported) and puts it as a background-image CSS to the closest parent with bgFromSrcSet class.

That itself would not be enough! So it also puts an interval checker on window load event to test if the load events have been completed, if not, it triggers them. (img load event is very often trigger only on first-time load, on following loads, image source could be retrieved from cache, resulting in img load event NOT being fired!)

jQuery(function($){ //ON DOCUMENT READY var $window = $(window); //prepare window as jQuery object var $srcSets = $('.srcSet'); //get all images with srcSet clas $srcSets.each(function(){ //for each .srcSet do... var $currImg = $(this); //prepare current srcSet as jQuery object $currImg .load(function(){ //bind the load event var img = $currImg.get(0); //retrieve DOM element from $currImg //test currentSrc support, if not supported, use the old src var src = img.currentSrc ? img.currentSrc : img.src; //To the closest parent with bgFromSrcSet class, //set the final src as a background-image CSS $currImg.closest('.bgFromSrcSet').css('background-image', "url('"+src+"')"); //remove processed image from the jQuery set //(to update $srcSets.length that is checked in the loadChecker) $srcSets = $srcSets.not($currImg); $currImg.remove(); //remove the <img ...> itself }) ; }); //window's load event is called even on following loads... $window.load(function(){ //prepare the checker var loadChecker = setInterval(function(){ if( $srcSets.length > 0 ) //if there is still work to do... $srcSets.load(); //...do it! else clearInterval(loadChecker); //if there is nothing to do - stop the checker }, 150); });
});

HTML

...could look like this:

<div> <img alt="" src="" srcset=" 5760w, 300w, 768w, 1024w, 1000w" sizes="(max-width: 2000px) 100vw, 2000px" > Something else...
</div>

Note: class bgFromSrcSet must not be set to the img itself! It can only be set to the elements in the img DOM parent tree.

0

I have used the Lazysizes plugin called bg-set for adding responsiveness to background images. It works similarly as srcset does and provides a set of multiple background images based on the device width.

<div>

The images in the data-bgset are the same, we are just providing the width specified image which the browser will be able to choose from.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like