img
具有srcset
属性看起来像是一种制作响应式图像的好方法。cssbackground-image
属性中是否存在等效的语法?
的HTML
<img src="small.jpg" srcset="medium.jpg 1000w, large.jpg 2000w" alt="yah">
的CSS
.mycontainer {
background: url(?something goes here?);
}
Answers:
image-set
是等效的CSS功能。我们应该在规范中添加等效的srcset功能(根据其尺寸定义资源)。
目前,它仅在带有-webkit-
前缀的Safari,Chrome和Opera中实现,并且仅支持x
描述符。
x
描述符似乎毫无意义,我的意思是背景图像在2倍“视网膜”台式机(5120w)上可能是全角,而在移动设备上以2倍(720w)的分辨率显示时,任何移动设备甚至都可以将其视为网页的大小可笑的图像背景。即使使用最大宽度的媒体查询来提供几种不同的大小也不是很有帮助,因为它不是背景容器的最大宽度,也不是屏幕的最大宽度。
可以肯定的是:
background: -webkit-image-set( url('path/to/image') 1x, url('path/to/high-res-image') 2x );
以相同的方式工作。浏览器将检查图像,查看最合适的图像并将使用该图像。
坦率地说,更健壮的另一种方法是使背景图像的特征和选项适应具有srcset属性的图像。
为此,将图像设置为width:100%; 高度:100%; 和对象适合:遮盖或包含。
这是一个例子:
.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 class="pseudo-background-img-container">
<img class="pseudo-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>
这可能不是每个人的最佳方法,但我想它会在没有任何JavaScript解决方法的情况下获得最理想的结果。
对于polyfill,您可以使用带有srcset的img作为下载正确图像尺寸的机制,然后使用JS隐藏它并设置父元素的背景图像。
这是一个小提琴:http : //jsbin.com/garetikubu/edit?html,输出
使用onload
JS作为阻止脚本并将其放入其中<head>
很重要。如果稍后再放脚本(例如末尾<body>
),则会出现竞争状态,浏览器尚未设置img.currentSrc。最好等待它被加载。
该示例使您可以查看正在下载的原始img。您可以使用一些CSS轻松隐藏它。
您可以根据需要使用媒体查询。这很容易:
.mycontainer {
background-image:url("img/image-big.jpg"); // big image
}
@media(max-width: 768px){
.mycontainer {
background-image:url("img/image-sm.jpg"); // small image
}
}
而且我认为它适用于所有支持媒体查询的浏览器;)
使用<picture>
element的类似解决方案:
此处为教程
教程案例:
我怀疑如果在较小的屏幕尺寸上使用相同的图像,图像的主要对象可能会变得过小。我想以不同的屏幕尺寸显示不同的图像(更侧重于主要主题),但是我仍然想基于设备像素比率显示同一图像的单独资源,并且我想自定义图像的高度和宽度基于视口的图像。
示例代码:
<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>
如果您使用的是Foundation框架(https://foundation.zurb.com/),则可以使用Interchange插件:
<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
responsive-loader
,以获得一个非常好的解决方案。
基于@Weston的答案,我建立了一个更通用的jQuery解决方案,您基本上可以只复制并粘贴JS和CSS并专注于HTML部分;)
...以确保图像在加载时几乎不可见
.srcSet{
position: fixed;
z-index: 0;
z-index: -1;
z-index: -100;
/* you could probably also add visibility: hidden; */
}
该脚本将遍历所有具有srcSet
class和bindload
事件的图像,这些事件将currentSrc
(或src
如果不支持)将其作为background-image
CSS放置到与bgFromSrcSet
class最接近的父级。
那本身还不够!因此,它还会在window
load
事件上放置一个间隔检查器,以测试加载事件是否已完成,如果尚未完成,则会触发它们。(img
load
事件往往引发只能在第一次加载,对以下负载,图像源可以从缓存中检索,导致IMG加载事件不被解雇!)
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);
});
});
...可能看起来像这样:
<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>
注:类bgFromSrcSet
必须不设置为img
自己!只能将其设置为img
DOM父树中的元素。