Есть ли эквивалент background-size: cover и contain для элементов изображения?

у меня есть сайт со многими страницами и различными фоновыми изображениями, и я отображаю их из CSS, как:

body.page-8 {
    background: url("../img/pic.jpg") no-repeat scroll center top #000;
    background-size: cover;
}

однако я хочу показать разные (полноэкранные) изображения на одной странице, используя <img> элементы, и я хочу, чтобы они имели те же свойства, что и выше background-image: cover; свойство (изображения не могут отображаться из CSS, они должны отображаться из HTML-документа).

обычно я использую:

div.mydiv img {
    width: 100%;
}

или:

div.mydiv img {
    width: auto;
}

сделать картинка полная и отзывчивая. Однако изображение слишком сильно сжимается (width: 100%), когда экран становится слишком узким, и показывает цвет фона тела в нижней части экрана. Другой метод,width: auto;, только изображение в полном размере и не реагирует на размер экрана.

есть ли способ отобразить изображение так же, как background-size: cover делает?

14 ответов


Решение #1-новое свойство object-fit (нет поддержки IE еще)

просто набор object-fit: cover; на img .

body {
  margin: 0;
}
img {
  display: block;
  width: 100vw;
  height: 100vh;
  object-fit: cover;
}
<img src="http://lorempixel.com/1500/1000" />

вы можете узнать больше об этом новом свойстве в этом статьи webplatform.

из приведенной выше статьи-относительно значения "обложки":

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

кроме того, здесь скрипка из приведенной выше статьи, которая демонстрирует все значения object-fit собственность.

решение #2-Замените img фоновым изображением на css

body {
  margin: 0;
}
img {
  position: fixed;
  width: 0;
  height: 0;
  padding: 50vh 50vw;
  background: url(http://lorempixel.com/1500/1000/city/Dummy-Text) no-repeat;
  background-size: cover;
}
<img src="http://placehold.it/1500x1000" />

есть на самом деле довольно простой решение css который даже работает на IE8:

.container {
  position: relative;
  overflow: hidden;
  /* Width and height can be anything. */
  width: 50vw;
  height: 50vh;
}

img {
  position: absolute;
  /* Position the image in the middle of its container. */
  top: -9999px;
  right: -9999px;
  bottom: -9999px;
  left: -9999px;
  margin: auto;
  /* The following values determine the exact image behaviour. */
  /* You can simulate background-size: cover/contain/etc.
     by changing between min/max/standard width/height values.
     These values simulate background-size: cover
  */
  min-width: 100%;
  min-height: 100%;
}
<div class="container">
    <img src="http://placehold.it/200x200" alt="" />
</div>

Если вы можете организовать контейнер элемент, который вы хотите заполнить, это, кажется, работает, но чувствует себя немного программистские. По сути, я просто использую min/max-width/height на большей площади, а затем масштабировать эту область обратно в исходные размеры.

.container {
  width: 800px;
  height: 300px;
  border: 1px solid black;
  overflow:hidden;
  position:relative;
}
.container.contain img {
  position: absolute;
  left:-10000%; right: -10000%; 
  top: -10000%; bottom: -10000%;
  margin: auto auto;
  max-width: 10%;
  max-height: 10%;
  -webkit-transform:scale(10);
  transform: scale(10);
}
.container.cover img {
  position: absolute;
  left:-10000%; right: -10000%; 
  top: -10000%; bottom: -10000%;
  margin: auto auto;
  min-width: 1000%;
  min-height: 1000%;
  -webkit-transform:scale(0.1);
  transform: scale(0.1);
}
<h1>contain</h1>
  <div class="container contain">
    <img 
       src="https://www.google.de/logos/doodles/2014/european-parliament-election-2014-day-4-5483168891142144-hp.jpg" 
       />
    <!-- 366x200 -->
  </div>
  <h1>cover</h1>
  <div class="container cover">
    <img 
       src="https://www.google.de/logos/doodles/2014/european-parliament-election-2014-day-4-5483168891142144-hp.jpg" 
       />
    <!-- 366x200 -->
  </div>

нет, вы не можете получить его достаточно как background-size:cover но..

этот подход довольно близок: он использует JavaScript, чтобы определить, является ли изображение пейзажем или портретом, и применяет стили соответственно.

JS

 $('.myImages img').load(function(){
        var height = $(this).height();
        var width = $(this).width();
        console.log('widthandheight:',width,height);
        if(width>height){
            $(this).addClass('wide-img');
        }else{
            $(this).addClass('tall-img');
        }
    });

в CSS

.tall-img{
    margin-top:-50%;
    width:100%;
}
.wide-img{
    margin-left:-50%;
    height:100%;
}

http://jsfiddle.net/b3PbT/


попробуйте и min-height и min-width С display:block:

img {
    display:block;
    min-height:100%;
    min-width:100%;
}

(скрипка)

при условии, что содержащий элемент вашего изображения position:relative или position:absolute изображение крышки контейнера. Однако она не будет центрирована.

вы можете легко центрировать изображение, если знаете, будет ли оно переполняться по горизонтали (set margin-left:-50%) или вертикально (set margin-top:-50%). Возможно, можно использовать медиа-запросы CSS (и некоторые математика), чтобы понять это.


что вы можете сделать, это использовать атрибут "style" для добавления фонового изображения в элемент, таким образом, вы все равно будете вызывать изображение в HTML, но вы все равно сможете использовать background-size: cover css behaviour:

HTML-код:

    <div class="image-div" style="background-image:url(yourimage.jpg)">
    </div>

CSS:

    .image-div{
    background-size: cover;
    }

вот как я добавляю поведение background-size: cover к элементам, которые мне нужно динамически загружать в HTML. Затем вы можете использовать удивительные классы css, такие как background-position: center. бум!--3-->


мне нужно было подражать background-size: contain, но не мог использовать object-fit из-за отсутствия поддержки. У моих изображений были контейнеры с определенными размерами, и это закончилось для меня:

.image-container {
  height: 200px;
  width: 200px;
  overflow: hidden;
  background-color: rebeccapurple;
  border: 1px solid yellow;
  position: relative;
}

.image {
  max-height: 100%;
  max-width: 100%;
  margin: auto;
  position: absolute;
  transform: translate(-50%, -50%);
  top: 50%;
  left: 50%;
}
<!-- wide -->
<div class="image-container">
  <img class="image" src="http://placehold.it/300x100">
</div>

<!-- tall -->
<div class="image-container">
  <img class="image" src="http://placehold.it/100x300">
</div>

Я нашел простое решение для эмуляции как обложки, так и содержимого, которое является чистым CSS и работает для контейнеров с динамическими размерами, а также не ограничивает соотношение изображений.

обратите внимание, что если вам не нужно поддерживать IE или Edge до 16, то вам лучше использовать object-fit.

фон-размер: обложка

.img-container {
  position: relative;
  overflow: hidden;
}

.background-image {
  position: absolute;
  min-width: 1000%;
  min-height: 1000%;
  left: 50%;
  top: 50%;
  transform: translateX(-50%) translateY(-50%) scale(0.1);
  z-index: -1;
}
<div class="img-container">
  <img class="background-image" src="https://picsum.photos/1024/768/?random">
  <p style="padding: 20px; color: white; text-shadow: 0 0 10px black">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
</div>

1000% использовано здесь в случае если размер изображения естественный большле чем размер он показывается. Например, если изображение 500x500, но контейнер только 200x200. С помощью этого решения изображение будет изменено до 2000x2000 (из-за минимальной ширины/минимальной высоты), а затем уменьшено до 200x200 (из-за transform: scale(0.1)).

фактор x10 может быть заменен на x100 или x1000, но обычно не идеально иметь изображение 2000x2000, отображаемое на 20x20 div. :)

background-size: contain

по тому же принципу, вы также можете использовать его, чтобы эмулировать background-size: contain:

.img-container {
  position: relative;
  overflow: hidden;
  z-index: 0;
}

.background-image {
  position: absolute;
  max-width: 10%;
  max-height: 10%;
  left: 50%;
  top: 50%;
  transform: translateX(-50%) translateY(-50%) scale(10);
  z-index: -1;
}
<div style="background-color: black">
  <div class="img-container">
    <img class="background-image" src="https://picsum.photos/1024/768/?random">
    <p style="padding: 20px; color: white; text-shadow: 0 0 10px black">
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
  </div>
</div>

для IE вам также нужно включить вторую ширину строки: 100%;

.mydiv img {
    max-width: 100%;
    width: 100%;
}

im не разрешено "добавить комментарий", так что делать это , Но да, что эру Пенкман сделал в значительной степени пятно на, чтобы получить его как фоновое покрытие все, что вам нужно сделать, это изменить

.tall-img{
    margin-top:-50%;
    width:100%;
}
.wide-img{
    margin-left:-50%;
    height:100%;
}

до

.wide-img{
    margin-left:-42%;
    height:100%;
}
.tall-img{
    margin-top:-42%;
    width:100%;
}

С помощью CSS вы можете имитировать object-fit: [cover|contain];. Это use transform и [max|min]-[width|height]. это не идеально. это не работает в одном случае: если изображение шире и короче контейнера.

.img-ctr{
  background: red;/*visible only in contain mode*/
  border: 1px solid black;
  height: 300px;
  width: 600px;
  overflow: hidden;
  position: relative;
  display: block;
}
.img{
  display: block;

  /*contain:*/
  /*max-height: 100%;
  max-width: 100%;*/
  /*--*/

  /*cover (not work for images wider and shorter than the container):*/
  min-height: 100%;
  width: 100%;
  /*--*/

  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
<p>Large square:
<span class="img-ctr"><img class="img" src="http://placehold.it/1000x1000"></span>
</p>
<p>Small square:
<span class="img-ctr"><img class="img" src="http://placehold.it/100x100"></span>
</p>
<p>Large landscape:
<span class="img-ctr"><img class="img" src="http://placehold.it/2000x1000"></span>
</p>
<p>Small landscape:
<span class="img-ctr"><img class="img" src="http://placehold.it/200x100"></span>
</p>
<p>Large portrait:
<span class="img-ctr"><img class="img" src="http://placehold.it/1000x2000"></span>
</p>
<p>Small portrait:
<span class="img-ctr"><img class="img" src="http://placehold.it/100x200"></span>
</p>
<p>Ultra thin portrait:
<span class="img-ctr"><img class="img" src="http://placehold.it/200x1000"></span>
</p>
<p>Ultra wide landscape (images wider and shorter than the container):
<span class="img-ctr"><img class="img" src="http://placehold.it/1000x200"></span>
</p>

Я знаю, что это старый, однако многие решения, которые я вижу выше, имеют проблему с изображением / видео, слишком большим для контейнера, поэтому на самом деле не действует как обложка фонового размера. Тем не менее, я решил сделать "служебные классы", чтобы он работал для изображений и видео. Вы просто даете контейнеру класс .media-cover-wrapper и сам элемент мультимедиа-класс .media-cover

тогда у вас есть следующий jQuery:

function adjustDimensions(item, minW, minH, maxW, maxH) {
  item.css({
  minWidth: minW,
  minHeight: minH,
  maxWidth: maxW,
  maxHeight: maxH
  });
} // end function adjustDimensions

function mediaCoverBounds() {
  var mediaCover = $('.media-cover');

  mediaCover.each(function() {
   adjustDimensions($(this), '', '', '', '');
   var mediaWrapper = $(this).parent();
   var mediaWrapperWidth = mediaWrapper.width();
   var mediaWrapperHeight = mediaWrapper.height();
   var mediaCoverWidth = $(this).width();
   var mediaCoverHeight = $(this).height();
   var maxCoverWidth;
   var maxCoverHeight;

   if (mediaCoverWidth > mediaWrapperWidth && mediaCoverHeight > mediaWrapperHeight) {

     if (mediaWrapperHeight/mediaWrapperWidth > mediaCoverHeight/mediaCoverWidth) {
       maxCoverWidth = '';
       maxCoverHeight = '100%';
     } else {
       maxCoverWidth = '100%';
       maxCoverHeight = '';
     } // end if

     adjustDimensions($(this), '', '', maxCoverWidth, maxCoverHeight);
   } else {
     adjustDimensions($(this), '100%', '100%', '', '');
   } // end if
 }); // end mediaCover.each
} // end function mediaCoverBounds

при вызове убедитесь, что позаботьтесь об изменении размера страницы:

mediaCoverBounds();

$(window).on('resize', function(){
  mediaCoverBounds();
});

затем следующий CSS:

.media-cover-wrapper {
  position: relative;
  overflow: hidden;
}

.media-cover-wrapper .media-cover {
  position: absolute;
  z-index: -1;
  top: 50%;
  left: 50%;
  -ms-transform: translate(-50%, -50%);
  -moz-transform: translate(-50%, -50%);
  -webkit-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
}

Да, это может потребовать jQuery, но он реагирует довольно хорошо и действует точно так же, как background-size: cover, и вы можете использовать его на изображении и/или видео, чтобы получить дополнительное значение SEO.


мы можем использовать подход масштабирования. Мы можем предположить, что максимум 30% (или более 100%) может быть эффектом масштабирования, если высота или ширина изображения меньше желаемой высоты или ширины. Мы можем скрыть остальную не необходимую область с переполнением: скрытый.

.image-container {
  width: 200px;
  height: 150px;
  overflow: hidden;
}
.stage-image-gallery a img {
  max-height: 130%;
  max-width: 130%;
  position: relative;
  top: 50%;
  left: 50%;
  transform: translateX(-50%) translateY(-50%);
}

это отрегулирует изображения с различной шириной или высотой.


background:url('/image/url/') right top scroll; 
background-size: auto 100%; 
min-height:100%;

встречаются же symptops. выше работал на меня.