Bezdepbonusu7Программирование: статьи и ответы

Вопрос

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

Автор вопроса: Martin AlgestenОтветов: 8

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

HTML

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

CSS

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

htmlcssbackground-imagesrcset

Ответы

Ответ 1 · рейтинг 92 · Yoav Weiss

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

В настоящее время реализовано во всех основных браузерах (Firefox, Chrome, Safari, Edge) с префиксом -webkit-. Safari поддерживает только дескрипторы x.

Ответ 2 · рейтинг 26 · SRing

Уверен, что:

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

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

Ответ 3 · рейтинг 25 · Parks

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

Для этого установите ширину изображения: 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.

Ответ 4 · рейтинг 11 · Weston

Для полифилла вы можете использовать img с srcset в качестве механизма для загрузки правильного размера изображения, затем использовать JS, чтобы скрыть его и установить фоновое изображение родительского элемента.

Вот скрипт: http://jsbin.com/garetikubu/edit?html,output

Использование onload и размещение JS в качестве блокирующего скрипта в <head> очень важно. Если вы поместите скрипт позже (скажем, в конце <body>), вы можете получить состояние гонки, когда img.currentSrc еще не был установлен браузером. Лучше дождаться загрузки.

Пример позволяет увидеть загружаемый исходный файл img. Вы можете легко скрыть это с помощью некоторого CSS.

Ответ 5 · рейтинг 10 · gtamborero

Вы можете использовать медиа-запросы для своих целей. Это просто:

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

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

И я думаю, что это работает во всех браузерах, поддерживающих медиа-запросы;)

Ответ 6 · рейтинг 3 · Piotr Ścigała

Аналогичное решение с использованием элемента <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>

Ответ 7 · рейтинг 2 · Martti Hyvönen

Если вы используете платформу 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

Ответ 8 · рейтинг 1 · jave.web

Основываясь на ответе @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

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

Этого самого по себе недостаточно! Поэтому он также помещает средство проверки интервала в событие 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! Его можно установить только для элементов в родительском дереве img DOM.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы