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


241

У меня есть сайт с большим количеством страниц и различными фоновыми изображениями, и я отображаю их из 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делается?


Отличный вопрос
wonsuc

Ответы:


380

Решение № 1 - Свойство подгонки объекта (отсутствует поддержка 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" />

Смотрите MDN - относительно object-fit: cover:

Размер заменяемого содержимого соответствует его пропорциям при заполнении всего поля содержимого элемента. Если соотношение сторон объекта не соответствует соотношению сторон его блока, то объект будет обрезан для соответствия.

Кроме того, посмотрите эту демонстрацию Codepen, которая сравнивает object-fit: coverпримененный к изображению с background-size: coverприложенным к фоновому изображению


Решение № 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" />


3
На момент написания этого комментария подгонка объектов еще не поддерживалась ни одной версией Internet Explorer (даже Edge). Это, однако, находится на рассмотрении .
Майк Корменди

3
Подгонка объекта все еще не поддерживается в IE. Я бы держался подальше, если бы на производственной площадке вы заботились о пользователях IE.
Трэвис Майкл Хеллер

2
Вы также можете добавить полифилл для # 1 для IE и старого Safari: github.com/bfred-it/object-fit-images
Валера Тумаш,

1
Осторожнее со вторым решением. Лучше не полагаться на vh на мобильных браузерах: nicolas-hoizey.com/2015/02/…
sudokai

1
@RoCk, вы можете найти такие вещи на caniuse: caniuse.com/#search=background-att :) PS Я думаю, что мы все можем быть уверены, что IE никогда не получит поддержку этой функции, и так как нет также и заполнения, мы ' переворачивать или зацикливаться на взломах JS / CSS, пока MS не решит, что пора (наконец) «убить» IE, удалив его из Windows.
SidOfc

31

На самом деле существует довольно простое решение 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>


9
Это не повторяет поведение прикрытия, но вместо этого обрезает центрированный участок из src img. См. Jsfiddle.net/sjt71j99/4 - первый img - это ваш урожай, следующий - background-size: cover, то есть то, что нам нужно, третий - оригинальный img. Я нашел для пейзажных изображений замену min-height и min-width на max-height: 100%; для портрета используйте max-width: 100%. Было бы хорошо, если бы было одно решение, которое работало бы или для пейзажа или для портрета. Любые идеи? Это лучшее кросс-браузерное решение, которое я когда-либо видел.
Terraling

1
Вы правы, это не делает то же самое, я пробовал кое-что, но кажется, что вы на самом деле не можете заставить его повторить покрытие на 100%, оно работает, пока изображение меньше контейнера в одном измерении хотя.
Саймон

@terraling, я знаю, что это старый комментарий, но проверь мой ответ . Он использует преобразование для позиционирования IMG в центре.
Тьяго Баркала

30

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


1
Полностью согласен. Это лучшее решение из всех вышеперечисленных для общего пользования.
Варис Витолс

Здорово. Это помогло мне. Спасибо
Раман Никиценка

14

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

Обратите внимание, что если вам не нужно поддерживать IE или Edge до 16, то вам лучше использовать подгонку объекта.

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

.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 дел. :)

background-size: содержит

Следуя тому же принципу, вы также можете использовать его для эмуляции 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>


Трюк с масштабом приведен уже здесь https://stackoverflow.com/a/28771894/2827823 , поэтому я не вижу смысла в публикации еще одного, как и transformво многих ответах
Ason

Если вы хотите расширить объяснение, обновите этот ответ вместо этого, поскольку нет необходимости в 2 с тем же решением
Ason

1
Спасибо за ваш комментарий @LGSon. Я не видел этот ответ раньше, но я все еще думаю, что мой ответ имеет здесь значение. Подход почти такой же, но, на мой взгляд, мой представлен немного чище. Многие другие ответы здесь представляют то же самое решение, и все они являются неполными (за исключением того, который вы связали). Так что, если мой ответ не должен быть здесь, то не должны другие.
Тьяго Баркала

1
Я обнаружил, что оно сжимает изображение в мобильном браузере Chrome на Android (протестировано на LG G3 и Samsung S9), я не тестировал его на Chrome на iOS, Firefox mobile на Android отображал его правильно.
Jecko

10

Нет , вы не можете получить это совсем как, 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/


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>


Вы можете использовать min-height: 100%; max-height:100%;и получить эквивалент background-size: cover;
Крис

min-height: 100%; max-height:100%;не будет сохранять соотношение сторон, поэтому не совсем эквивалентно.
Reedyn

2

Попробуйте установить как min-height и min-widthс display:block:

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

( скрипка )

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

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


2

С помощью CSS вы можете моделировать object-fit: [cover|contain];. Это использовать 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>


2

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

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. бум


1
Главным образом разделение проблем, но вот несколько других: programmers.stackexchange.com/a/271338
Daan

0

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

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

0

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

.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%;
}


0

Я знаю, что это старо, однако многие решения, которые я вижу выше, имеют проблему с изображением / видео, которое слишком велико для контейнера, поэтому фактически не действует как крышка размера фона. Однако я решил создать «служебные классы», чтобы они работали с изображениями и видео. Вы просто передаете контейнеру класс .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.


0

Мы можем принять ZOOM подход. Мы можем предположить, что максимум 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%);
}

Это позволит настроить изображения с различной шириной или высотой.


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

встречал такие же точные симптопы. выше работал для меня.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.