Размер CSS изображения, как заполнить, а не растянуть?

415

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

Но если я установлю ширину и высоту с помощью css ( width:150px; height:100px), изображение будет растянуто, и это может быть некрасиво.

Как заполнить изображения до определенного размера с помощью CSS, а не растягивать его?

Пример заливки и растяжения изображения:

Исходное изображение:

оригинал

Растянутое изображение:

Натяжные

Заполненное изображение:

Заполненный

Обратите внимание, что в приведенном выше примере с заполненным изображением: сначала размер изображения изменяется до 150x255 (с сохранением соотношения сторон), а затем обрезается до 150x100.

Махди Гиаси
источник
Попробуйте просто установить widthи heightследует настроить соответственно
NewInTheBusiness
3
Она простирается изображение. смотрите это: jsfiddle.net/D7E3E
Махди Гиаси
Требуется часть изображения без изменения размера!
Али Бен Мессауд
3
Крис Койер также имеет несколько хороших решений для этого: css-tricks.com/perfect-full-page-background-image
ambiguousmouse
1
ОЧЕНЬ ВАЖНО: это невероятно плохая практика для целей SEO. Если вы используете его в качестве фонового изображения, значит, оно работает нормально, но если вы хотите, чтобы изображение было найдено Google, оно НЕ будет проиндексировано, если это только фоновое изображение.
Алекс Банман

Ответы:

395

Если вы хотите использовать изображение в качестве фона CSS, есть элегантное решение. Просто используйте coverили containв background-sizeсвойстве CSS3.

.container {
  width: 150px;
  height: 100px;
  background-image: url("http://i.stack.imgur.com/2OrtT.jpg");
  background-size: cover;
  background-repeat: no-repeat;
  background-position: 50% 50%;
}
<div class="container"></div>

Пока coverдаст вам уменьшенное изображение, containдаст вам уменьшенное изображение. Оба сохранят пропорции пикселя.

http://jsfiddle.net/uTHqs/ (используя обложку)

http://jsfiddle.net/HZ2FT/ (с использованием содержимого)

Этот подход имеет преимущество в том, что он дружелюбен к дисплеям Retina согласно краткому руководству Thomas Fuchs

Стоит отметить, что поддержка браузером обоих атрибутов исключает IE6-8.

Марсело Де Полли
источник
1
Поскольку вы можете изменять размер изображения исключительно в CSS, это позволяет вам использовать большое изображение, а затем уменьшать его в соответствии с плотностью пикселей каждого устройства с помощью медиазапросов.
Марсело Де Полли
1
Не могли бы вы объяснить, почему в этом случае положение фона, по-видимому, указывает положение центра изображения, а не его верхнего левого угла? Является ли это следствием background-size: cover?
Маттео
1
моя просто охватывает весь DIV, расширяя изображение. Я не вижу окончания кривой.
SearchForKnowledge
3
Для чего background-repeat: no-repeat;? Если изображение покрывает его контейнер, оно все равно не повторится.
lurkit
3
'background-position' также может быть установлена ​​в 'center center'. например: .container {... background-position: center center; }
Лео Рибейро
556

Вы можете использовать свойство css object-fit.

.cover {
  object-fit: cover;
  width: 50px;
  height: 100px;
}
<img src="http://i.stack.imgur.com/2OrtT.jpg" class="cover" width="242" height="363" />

Смотрите пример здесь

Есть полифилл для IE: https://github.com/anselmh/object-fit

afonsoduarte
источник
11
Интересно видеть, что это можно сделать и с помощью imgтегов (не только background-imageметодом, описанным в ответе выше). Спасибо :)
Махди Гиаси
44
Рассматривая это как вариант, имейте в виду, что object-fit не поддерживается во многих браузерах .
Joshreesjones
2
К сожалению, background-sizeв моих проектах редко бывает приемлемым решением. Вы с меньшей вероятностью получите какую-либо выгоду от SEO и не можете предоставить тег ALT, заголовок и т. Д., Сопровождающие изображение, где вы можете предоставить дополнительный контекст для программ чтения с экрана.
Маркус
3
Это круто, но нет поддержки IE. Ни один из полифилов больше не работает.
Джейк,
3
Просто использование object-fit: cover;делает это. Большое спасибо
Лука
67

Улучшение в ответе выше @afonsoduarte ( НЕ принятый) .
если вы используете загрузчик


Есть три различия:

  1. Обеспечение width:100%по стилю.
    Это полезно, если вы используете загрузчик и хотите, чтобы изображение растягивалось на всю доступную ширину.

  2. Указывать heightсвойство необязательно, Вы можете удалить / оставить его по своему усмотрению.

    .cover {
       object-fit: cover;
       width: 100%;
       /*height: 300px;  optional, you can remove it, but in my case it was good */
    }
  3. Кстати, нет никакой необходимости , чтобы обеспечить heightи widthатрибуты на imageэлементе , поскольку они будут переписаны стилем.
    так что достаточно написать что-то вроде этого.

    <img class="cover" src="url to img ..."  />
Хакан Фистик
источник
1
Именно то, что я искал.
Фрэнсис Лантье
1
Тебе нужен поцелуй!
Цинь Ван
объектная подгонка не работает с IE?
bgcode
1
это 2020, я думаю, что это хорошее время отказаться от IE
Хакан Фистик
56

Единственный реальный способ - создать контейнер вокруг изображения и использовать overflow:hidden:

HTML

<div class="container"><img src="ckk.jpg" /></div>

CSS

.container {
    width: 300px;
    height: 200px;
    display: block;
    position: relative;
    overflow: hidden;
}

.container img {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
}

В CSS трудно делать то, что вы хотите, и центрировать изображение, в jquery есть быстрое решение, такое как:

var conHeight = $(".container").height();
var imgHeight = $(".container img").height();
var gap = (imgHeight - conHeight) / 2;
$(".container img").css("margin-top", -gap);

http://jsfiddle.net/x86Q7/2/

Доминик Грин
источник
1
Спасибо. это сработало, но оно обрезает изображение сверху . (см .: jsfiddle.net/x86Q7 ) Нет ли способа обрезать изображение из центра ?
Махди Гиаси
1
@MahdiGhiasi: измените верхний и левый свойства в .container img css !!
Али Бен Мессауд
Я могу установить набор margin-topизображений, например 50px(см. Это: jsfiddle.net/x86Q7/1 ), но как обрезать его из реального центра ? (Без jQuery?)
Махди Гиаси
2
Ах, извините, я не видел ваш комментарий, но я добавил jquery, просто добавив :)
Доминик Грин,
1
Отличное решение! Для меня вертикальная заливка была более важной, чем горизонтальная, поэтому мне просто пришлось изменить «width: 100%» на «height: 100%» для класса «.container img». Спасибо!
deebs
26

Решение CSS без JS и без фонового изображения:

Метод 1 «маржинальное авто» (IE8 + - НЕ FF!):

div{
  width:150px; 
  height:100px; 
  position:relative;
  overflow:hidden;
}
div img{
  position:absolute; 
  top:0; 
  bottom:0; 
  margin: auto;
  width:100%;
}
<p>Original:</p>
<img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>

<p>Wrapped:</p>
<div>
  <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
</div>

http://jsfiddle.net/5xjr05dt/

Способ 2 «преобразования» (IE9 +):

div{
  width:150px; 
  height:100px; 
  position:relative;
  overflow:hidden;
}

div img{
  position:absolute; 
  width:100%;
  top: 50%;
  -ms-transform: translateY(-50%);
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
}
<p>Original:</p>
<img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>

<p>Wrapped:</p>
<div>
  <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
</div>

http://jsfiddle.net/5xjr05dt/1/

Метод 2 можно использовать для центрирования изображения в контейнере с фиксированной шириной / высотой. Оба могут переполниться - и если изображение меньше контейнера, оно все равно будет отцентрировано.

http://jsfiddle.net/5xjr05dt/3/

Способ 3 «двойная обертка» (IE8 + - НЕ FF!):

.outer{
  width:150px; 
  height:100px; 
  margin: 200px auto; /* just for example */
  border: 1px solid red; /* just for example */
  /* overflow: hidden;	*/ /* TURN THIS ON */
  position: relative;
}
.inner { 
    border: 1px solid green; /* just for example */
    position: absolute;
    top: 0;
    bottom: 0;
    margin: auto;
    display: table;
    left: 50%;
}
.inner img {
    display: block;
    border: 1px solid blue; /* just for example */
    position: relative;
    right: 50%;
    opacity: .5; /* just for example */
}
<div class="outer">
  <div class="inner">
     <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
  </div>
</div>

http://jsfiddle.net/5xjr05dt/5/

Метод 4 «Двойная обертка И двойное изображение» (IE8 +):

.outer{
  width:150px; 
  height:100px; 
  margin: 200px auto; /* just for example */
  border: 1px solid red; /* just for example */
  /* overflow: hidden;	*/ /* TURN THIS ON */
  position: relative;
}
.inner { 
    border: 1px solid green; /* just for example */
    position: absolute;
    top: 50%;
    bottom: 0;
    display: table;
    left: 50%;
}
.inner .real_image {
    display: block;
    border: 1px solid blue; /* just for example */
    position: absolute;
    bottom: 50%;
    right: 50%;
    opacity: .5; /* just for example */
}

.inner .placeholder_image{
  opacity: 0.1; /* should be 0 */
}
<div class="outer">
  <div class="inner">
    <img class="real_image" src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
    <img class="placeholder_image"  src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
  </div>
</div>

http://jsfiddle.net/5xjr05dt/26/

  • Метод 1 имеет немного лучшую поддержку - вы должны установить ширину ИЛИ высоту изображения!
  • С префиксами метод 2 также имеет достойную поддержку (от ie9 и выше) - Метод 2 не поддерживается в Opera mini!
  • Метод 3 использует две обертки - может переполнять ширину и высоту.
  • В методе 4 используется двойное изображение (одно в качестве заполнителя), что дает дополнительную нагрузку на полосу пропускания, но еще лучше поддерживает кроссбраузер.

Методы 1 и 3 не работают с Firefox

JT Houtenbos
источник
Это единственный, который действительно работает (минус решения JS). Спасибо!
Джейк,
Это ограничено переполнением или высотой или шириной, но интересное решение.
Джейк,
1
@Jake - Можно переполнить ширину и высоту с помощью метода 2 выше - см. Мой обновленный ответ с дополнительной скрипкой.
JT Houtenbos
Да. Это определенно отличный ответ. Я буду дурачиться с этим еще немного. Это было немного странно для изображения шире, чем выше, который должен был быть отзывчивым, но есть много приложений для этого.
Джейк
1
@ Джейк - Круто - я нашел 3-й метод для горизонтального центрирования. Я расширил этот метод, чтобы также поддерживать вертикальное центрирование. Я опубликую свое добавление как 3-й метод выше. Кажется, это IE7 + доказательство (возможно, даже ниже). Вот оригинальный ответ: stackoverflow.com/questions/3300660/…
JT Houtenbos
10

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

Затем вы можете сделать это с помощью imgтега и просто установить максимальную ширину и максимальную высоту для элемента.

CSS:

.imgContainer {
    display: block;
    width: 150px; 
    height: 100px;
}

.imgContainer img {
    max-width: 100%;
    max-height: 100%;
}

HTML:

<div class='imgContainer'>
    <img src='imagesrc.jpg' />
</div>

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

Если вы хотите центрировать изображение по вертикали и горизонтали, вы можете изменить контейнер css на:

.imgContainer {
    display: table-cell;
    width: 150px; 
    height: 100px;
    text-align: center;
    vertical-align: middle;
}

Вот JS Fiddle http://jsfiddle.net/9kUYC/2/

earl3s
источник
Это не то же самое, что покрытие в CSS, где одно из результирующих измерений всегда превышает 100% (или равно в
крайнем
Нет, это решение гарантирует, что оно никогда не выходит за пределы 100%, о чем и шла речь. Они не хотели, чтобы изображение искажалось или выходило за рамки первоначальных размеров.
earl3s
3
Вопрос был «Как заполнить» с примером заполненного изображения, которое явно обрезано.
Мирошко
Но что, если вам нужно изображение, чтобы быть отзывчивым? Определение определенной ширины и высоты не сработает 😕
Рикардо
2
Это было то, что мне было нужно. Спасибо!
Нико Родсевич
5

Основываясь на ответе @Dominic Green, используя jQuery, вот решение, которое должно работать для изображений, которые шире, чем они высоки, или выше, чем они широки.

http://jsfiddle.net/grZLR/4/

Вероятно, есть более элегантный способ сделать JavaScript, но это работает.

function myTest() {
  var imgH = $("#my-img").height();
  var imgW = $("#my-img").width();
  if(imgW > imgH) {
    $(".container img").css("height", "100%");
    var conWidth = $(".container").width();
    var imgWidth = $(".container img").width();
    var gap = (imgWidth - conWidth)/2;
    $(".container img").css("margin-left", -gap);
  } else {
    $(".container img").css("width", "100%");
    var conHeight = $(".container").height();
    var imgHeight = $(".container img").height();
    var gap = (imgHeight - conHeight)/2;
    $(".container img").css("margin-top", -gap);
  }
}
myTest();
ramdog
источник
5
  • Не использовать фон CSS
  • Только 1 div, чтобы обрезать его
  • Уменьшен до минимальной ширины, чтобы сохранить правильное соотношение сторон
  • Обрезать от центра (по вертикали и горизонтали, вы можете отрегулировать это с помощью верхней, левой и трансформации)

Будьте осторожны, если вы используете тему или что-то, они часто объявляют img max-width на 100%. Вы должны сделать ничего. Проверьте это :)

https://jsfiddle.net/o63u8sh4/

<p>Original:</p>
<img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>

<p>Wrapped:</p>
<div>
    <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
</div>


div{
  width:150px; 
  height:100px; 
  position:relative;
  overflow:hidden;
}
div img{
  min-width:100%;
  min-height:100%;
  height:auto;
  position:relative;
  top:50%;
  left:50%;
  transform:translateY(-50%) translateX(-50%);
}
dmegatool
источник
Это является ответом я искал.
Маркос
Это то, чем я давно хотел заниматься, спасибо;)
Босс КОТИГА
4

Я помог создать плагин jQuery под названием Fillmore , который обрабатывает background-size: coverбраузеры, которые его поддерживают, и имеет шим для тех, кто этого не делает. Посмотри!

Эйдан Фельдман
источник
4

Я думаю, что уже довольно поздно для этого ответа. В любом случае, надеюсь, это поможет кому-то в будущем. Я столкнулся с проблемой позиционирования карт в угловом положении. Есть карты, отображаемые для массива событий. Если ширина изображения события велика для карты, изображение должно быть показано обрезкой с двух сторон и высотой 100%. Если высота изображения длинная, нижняя часть изображения обрезается, а ширина составляет 100%. Вот мое чистое решение CSS для этого:

введите описание изображения здесь

HTML:

 <span class="block clear img-card b-b b-light text-center" [ngStyle]="{'background-image' : 'url('+event.image+')'}"></span>

CSS

.img-card {
background-repeat: no-repeat;
background-size: cover;
background-position: 50% 50%;
width: 100%;
overflow: hidden;
}
Nodirabegimxonoyim
источник
я не могу понять, как это работает, но это работает. Вам нужно расположить диапазон абсолютно сверху: 0; справа: 0; снизу: 0; слева: 0 внутри относительно позиционированного родителя, чтобы измерить его.
Майк
Спасибо за отзыв, дорогой Майк, я рад, если это было полезно. Вы хотите, чтобы я обновил ответ вашим комментарием?
Nodirabegimxonoyim
3

Попробуйте что-то вроде этого: http://jsfiddle.net/D7E3E/4/

Использование контейнера с переполнением: скрыто

РЕДАКТИРОВАТЬ: @ Доминик Грин избил меня.

woutr_be
источник
Спасибо. это сработало, но оно обрезает изображение сверху . (см .: jsfiddle.net/x86Q7 ) Нет ли способа обрезать изображение из центра ?
Махди Гиаси
С CSS может быть довольно сложно, это лучшее, что я мог придумать для jsfiddle.net/D7E3E/5
woutr_be
Да, чтобы правильно отцентрировать его, вы должны использовать jQuery, может быть, намного проще.
woutr_be
3

Это позволит заполнить изображения до определенного размера, не растягивая его или не обрезая его

img{
    width:150px;  //your requirement size
    height:100px; //your requirement size

/*Scale down will take the necessary specified space that is 150px x 100px without stretching the image*/
    object-fit:scale-down;
}
Манодж Сельвин
источник
2

Чтобы разместить изображение в полноэкранном режиме, попробуйте это:

повторение фона: круглый;

suyash1798
источник