是否有CSS背景图片的srcset等效项


89

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:


81

image-set是等效的CSS功能。我们应该在规范中添加等效的srcset功能(根据其尺寸定义资源)。

目前,它仅在带有-webkit-前缀的Safari,Chrome和Opera中实现,并且仅支持x描述符。


1
是否有任何优美的后备支持或polyfill支持呢?
Rachel Cantor

5
@RachelCantor是否需要回退?我想过,只有现代设备才会有视网膜屏幕。
James Kemp

3
仅支持x描述符似乎毫无意义,我的意思是背景图像在2倍“视网膜”台式机(5120w)上可能是全角,而在移动设备上以2倍(720w)的分辨率显示时,任何移动设备甚至都可以将其视为网页的大小可笑的图像背景。即使使用最大宽度的媒体查询来提供几种不同的大小也不是很有帮助,因为它不是背景容器的最大宽度,也不是屏幕的最大宽度。
克里斯·塞弗特

1
因此,如果浏览器不支持图像设置,那么后备功能是什么?
O.MeeKoh

22

可以肯定的是:

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

以相同的方式工作。浏览器将检查图像,查看最合适的图像并将使用该图像。


2
在2018年,并非所有浏览器都支持此功能。caniuse.com/#search=image-set
BadHorsie

14

坦率地说,更健壮的另一种方法是使背景图像的特征和选项适应具有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解决方法的情况下获得最理想的结果。


1
src-set不考虑图像宽度,仅考虑对象适合的容器宽度:封面。这意味着,如果您的img标记最终说的是50px宽但高为1000px,则满足50px宽的图像将被加载并拉伸以适合(可能从240w缩放到1500px宽),以仅显示50px的切片。
克里斯·塞弗特

10

对于polyfill,您可以使用带有srcset的img作为下载正确图像尺寸的机制,然后使用JS隐藏它并设置父元素的背景图像。

这是一个小提琴:http : //jsbin.com/garetikubu/edit?html,输出

使用onloadJS作为阻止脚本并将其放入其中<head>很重要。如果稍后再放脚本(例如末尾<body>),则会出现竞争状态,浏览器尚未设置img.currentSrc。最好等待它被加载。

该示例使您可以查看正在下载的原始img。您可以使用一些CSS轻松隐藏它。


有趣。我本来希望图像在执行此操作时加载两次。但是,它似乎没有。
佩里

8

您可以根据需要使用媒体查询。这很容易:

.mycontainer {    
    background-image:url("img/image-big.jpg"); // big image   
}

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

而且我认为它适用于所有支持媒体查询的浏览器;)


2
如果将图像设置为覆盖容器,则不会考虑将图像拉伸到适合其高度的程度,则该框可能是原始图像宽度高度的2或3倍,因此看起来质量很差。
克里斯·塞弗特

3

使用<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>

将“ <图片>”元素定位为“绝对”或“固定”。设置正确的z-index + position:如果需要,相对于其容器
PiotrŚcigała17年

gdaniel:Ready JS解决方案:github.com/code-mattclaffey/…我刚刚对其进行了测试,并且效果很好!
PiotrŚcigała17年

JS溶液,经由<画面>元素加载图像并显示它作为一个背景图像:github.com/code-mattclaffey/...
彼得Ścigała

2

如果您使用的是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


感谢这个Martti。我现在将它与webpack一起很好地连接起来responsive-loader,以获得一个非常好的解决方案。
fredrivett

1

基于@Weston的答案,我建立了一个更通用的jQuery解决方案,您基本上可以只复制并粘贴JS和CSS并专注于HTML部分;)

TL; DR-小提琴: https //jsfiddle.net/dpaa7oz6/

的CSS

...以确保图像在加载时几乎不可见

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

JS / jQuery

该脚本将遍历所有具有srcSetclass和bindload事件的图像,这些事件将currentSrc(或src如果不支持)将其作为background-imageCSS放置到与bgFromSrcSetclass最接近的父级。

那本身还不够!因此,它还会在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);  
  });

});

的HTML

...可能看起来像这样:

<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自己!只能将其设置为imgDOM父树中的元素。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.