Есть ли эквивалент srcset для фонового изображения css

img С выглядит как отличный способ сделать отзывчивые изображения. Есть ли эквивалентный синтаксис, который работает в css background-image собственность?

HTML-код

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

в CSS

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

8 ответов


image-set является эквивалентной функцией CSS. Мы должны добавить эквивалентную функциональность srcset (определение ресурсов в соответствии с их измерениями) в спецификацию.

В настоящее время он реализован только в Safari, Chrome и Opera с помощью -webkit- префикс, и это только поддерживает x дескрипторов.


почти уверен, что:

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

работает так же. Браузер изучит изображения, посмотрит, что подходит лучше всего, и будет использовать этот.


для polyfill вы можете использовать img с srcset в качестве механизма для загрузки правильного размера изображения, а затем использовать 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> элемент: обучение

случай учебника:

Я сомневаюсь, что если я использую то же изображение для меньшего размера экрана, основной предмет моего изображения может стать слишком маленьким по размеру. Я хочу чтобы отобразить другое изображение (более сфокусированное на основном предмете) в другой размер экрана, но я все еще хочу отображать отдельные активы того же изображения, основанного на соотношении устройство-пиксель, и я хочу персонализировать высота и ширина изображения на основе просмотра.

пример кода:

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

на основе @Westonответ, я построил более общее решение jQuery, вы можете в основном просто скопировать и вставить JS и CSS и сосредоточиться на HTML-части;)

TL; DR-fiddle: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

этот скрипт будет пройти через все изображения, которые srcSet - классом и связать load событие, которое занимает currentSrc (или src если не поддерживается) и ставит его как background-image CSS для ближайшего родителя с bgFromSrcSet класса.

этого самого было бы недостаточно! таким образом, он также ставит интервальную проверку на window load событие, чтобы проверить, если события загрузки были завершены, если нет, он запускает их. (img load событие очень часто вызывают только при первой загрузке, на следующих нагрузках, Источник изображения смог быть извлечено из кэша,в результате img load event не уволили!)

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 родительское дерево DOM.


другой подход, который является откровенно более надежным, заключается в адаптации характеристик и параметров фоновых изображений к изображению с атрибутом srcset.

чтобы сделать это, установите изображение в ширину: 100%; высота: 100%; и объект-fit: обложка или содержать.

вот пример:

.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>

Это может быть не лучший подход для всех, но я думаю, что он получит большинство желаемых результатов без каких-либо обходной путь javascript.


Если вы используете Foundation framework (https://foundation.zurb.com/), Вы можете использовать плагин обмена для этого:

<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