问题
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(?something goes here?);
}
回答1:
image-set is the equivalent CSS feature. We should add equivalent srcset functionality (defining resources according to their dimensions) to the spec.
Currently it's only implemented in Safari, Chrome and Opera with the -webkit-
prefix, and it's only support the x
descriptors.
回答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.
回答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: http://jsbin.com/garetikubu/edit?html,output
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.
回答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:
.psuedo-background-img-container {
position: relative;
width:400px;
height: 200px;
}
.psuedo-background-img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="psuedo-background-img-container">
<img class="psuedo-background-img" src="https://cdn3.tnwcdn.com/wp-content/blogs.dir/1/files/2016/12/Keep.jpg" srcset="https://cdn0.tnwcdn.com/wp-content/blogs.dir/1/files/2016/12/Keep.jpg 640w, https://cdn0.tnwcdn.com/wp-content/blogs.dir/1/files/2016/12/Keep-280x175.jpg 280w, https://cdn0.tnwcdn.com/wp-content/blogs.dir/1/files/2016/12/Keep-432x270.jpg 432w, https://cdn0.tnwcdn.com/wp-content/blogs.dir/1/files/2016/12/Keep-216x135.jpg 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.
回答5:
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 ;)
回答6:
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>
回答7:
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: https://jsfiddle.net/dpaa7oz6/
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 class="bgFromSrcSet">
<img class="srcSet"
alt=""
src="http://example.com/something.jpeg"
srcset="http://example.com/something.jpeg 5760w, http://example.com/something-300x200.jpeg 300w, http://example.com/something-768x512.jpeg 768w, http://example.com/something-1024x683.jpeg 1024w, http://example.com/something-1000x667.jpeg 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.
回答8:
If you are using Foundation framework (https://foundation.zurb.com/), you can use Interchange plugin for that:
<div data-interchange="[assets/img/interchange/small.jpg, small],
[assets/img/interchange/medium.jpg, medium],
[assets/img/interchange/large.jpg, large]">
</div>
https://foundation.zurb.com/sites/docs/interchange.html#use-with-background-images
来源:https://stackoverflow.com/questions/26801745/is-there-a-srcset-equivalent-for-css-background-image