Масштабировать изображение по размеру ограничивающей рамки

117

Есть ли решение только для css для масштабирования изображения в ограничивающую рамку (с сохранением соотношения сторон)? Это работает, если изображение больше контейнера:

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

Пример:

Но я хочу увеличить изображение до тех пор, пока размер контейнера не станет 100%.

Томас Гиллори
источник
Вы имеете в виду высоту: 100% и ширину: 100%? у вас есть желаемое измерение, которого вы хотите достичь? в противном случае вы также можете растянуть изображение и заставить его достичь этих размеров.
mikevoermans
@mikevoermans Посмотрите на мои два первых примера: я хочу растянуть изображение до тех пор, пока одно из измерений не станет 100%, а другое не станет <= 100%
Томас Гиллори
@jacktheripper Конечно, сохранение соотношения сторон ...
Томас Гиллори
@gryzzly Примеры говорят сами за себя! Если бы они посмотрели на примеры, это было бы очевидно.
Томас Гиллори
@Artimuz Я полностью не согласен. Три ответа на ваши вопросы (включая мой) предполагают, что это НЕ было очевидно.
Хан

Ответы:

94

Примечание. Несмотря на то, что это принятый ответ, приведенный ниже ответ более точен и в настоящее время поддерживается во всех браузерах, если у вас есть возможность использовать фоновое изображение.

Нет, нет единственного способа сделать это в обоих направлениях с помощью CSS. Вы могли бы добавить

.fillwidth {
    min-width: 100%;
    height: auto;
}

Чтобы элемент всегда имел 100% ширину и автоматически масштабировал высоту до соотношения сторон или наоборот:

.fillheight {
    min-height: 100%; 
    width: auto;
}

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

Причина в том, что CSS не знает, как выглядит страница. Он заранее устанавливает правила, но только после этого элементы визуализируются, и вы точно знаете, с какими размерами и соотношениями вы имеете дело. Единственный способ обнаружить это - с помощью JavaScript.


Хотя вы не ищете JS-решение, я все равно добавлю его, если оно кому-то понадобится. Самый простой способ справиться с этим с помощью JavaScript - добавить класс, основанный на разнице в соотношении. Если отношение ширины к высоте поля больше, чем у изображения, добавьте класс fillwidth, иначе добавьте класс fillheight.

Стефан Мюллер
источник
7
На самом деле есть решение: установить CSS3 background-size как contain. Смотрите мой ответ.
Томас Гиллори
Вы совершенно правы. Несмотря на то, что прошло уже полтора года, я отредактировал свой пост.
Стефан Мюллер
4
Я бы сказал, что это правильный ответ на заданный вопрос, а именно, что такое CSS для тега img. Это актуально, потому что семантически тег img является содержимым, а изображение в качестве фона для div - нет. В то время как некоторые обстоятельства делают это непрактичным (если вы не знаете соотношение изображения и контейнера), для других это совершенно правильно. Спасибо.
duncanwilcox 02
173

Благодаря CSS3 есть решение!

Решение состоит в том, чтобы поместить изображение как, background-imageа затем установить background-sizeзначение contain.

HTML

<div class='bounding-box'>
</div>

CSS

.bounding-box {
  background-image: url(...);
  background-repeat: no-repeat;
  background-size: contain;
}

Проверьте это здесь: http://www.w3schools.com/cssref/playit.asp?filename=playcss_background-size&preval=contain

Полная совместимость с последними версиями браузеров: http://caniuse.com/background-img-opts

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

.bounding-box {
  background-image: url(...);
  background-size: contain;
  position: absolute;
  background-position: center;
  background-repeat: no-repeat;
  height: 100%;
  width: 100%;
}
Томас Гиллори
источник
1
Хороший, хотя мой ответ не является неверным (вы спрашивали конкретно об img), это отличное решение, и я должен был подумать об этом. Единственная проблема заключается в том, что IE 8 по-прежнему настолько широко используется, что я бы не стал на это полагаться, но тем не менее, приятный улов.
Стефан Мюллер
6
Установите его на «обложку», если не хотите использовать почтовый ящик: background-size: contain;
arxpoetica 06
3
Следует отметить , что вы можете вводить URL - изображения с HTML: <div class=image style="background-image: url('/images/foo.jpg');"></div>. Все остальные стили следует применять с помощью CSS.
Андрей Михайлов - lolmaus
14
Я бы сказал, что это ужасный подход. Изменяя его на фоновое изображение, вы удаляете семантическое значение изображения в HTML.
animuson
14
@animuson: Мне все еще помогло, так как я использую HTML / CSS для печатных отчетов и не могу
похвастаться
37

Вот хакерское решение, которое я обнаружил:

#image {
    max-width: 10%;
    max-height: 10%;
    transform: scale(10);
}

Это увеличит изображение в десять раз, но ограничит его до 10% от его окончательного размера - таким образом, привязав его к контейнеру.

В отличие от background-imageрешения, это также будет работать с <video>элементами.

Интерактивный пример:

Владимир Пантелеев
источник
1
Мне нравится это решение. Он не только действительно отвечает на вопрос (я знаю, что за мысль), он прекрасно работает во всех современных браузерах, не прибегая к Javascript!
ndm13 02
2
Я бы хотел увидеть скрипку из этого. В моем тесте размещения img в контейнере 400x400 img просто обрезается в углу
cyberwombat
3
Хороший ответ! @Yashua Вам нужно добавить, transform-origin: top leftчтобы остановить обрезку. / Zombie
XwipeoutX
Brilliant. Единственное, что меня беспокоит, это возможная потеря качества изображения в браузере с плохим кодом, но теоретически все должно работать нормально!
Codemonkey
Интересно, но не работает в Chrome. В результате получается обрезанная строка изображения.
MattK
23

Сегодня просто скажите объектно-подходящий: содержать. Поддержка - это все, кроме IE: http://caniuse.com/#feat=object-fit

Гленн Мейнард
источник
3
На момент написания этой статьи (09.12.2016, 10:56) IE имеет только около 16% рынка и продолжает сокращаться, так что это лучший ответ для меня: D
Чжан
8
Не редактируйте ответы других людей, чтобы исправить что-то, кроме опечаток или неработающих ссылок. Я бы не сказал что-то детское вроде «Есть полифилл для дерьмовых браузеров» в SO-ответе, и мне не нравится, что мой ответ отредактировали, чтобы он выглядел так, как я сказал. если вы хотите использовать свои слова, вставьте их в свой ответ.
Гленн Мейнард,
Я бы сказал, проблема не в IE, а в Edge. По словам caniuse, object-fitон все еще находится в стадии разработки.
BairDev
Это должен быть один из самых популярных ответов в 2017 году и далее ... Согласно приведенной выше ссылке caniuse, 90% всех пользователей во всем мире теперь используют браузер, который поддерживает это,
fgblomqvist
Я только что опубликовал ответ, который работает с и без object-fit: stackoverflow.com/a/46456673/474031
gabrielmaldi
8

HTML:

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

CSS:

.container{
  width: 100px;
  height: 100px;
}


.flowerImg{
  width: 100px;
  height: 100px;
  object-fit: cover;
  /*object-fit: contain;
  object-fit: scale-down;
  object-position: -10% 0;
  object-fit: none;
  object-fit: fill;*/
}
Deke
источник
5

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

Вот фрагмент, который работает в Chrome, Firefox и Safari (как с его использованием object-fit: scale-down, так и без него):

figure {
  margin: 0;
}

.container {
  display: table-cell;
  vertical-align: middle;
  width: 80px;
  height: 80px;
  border: 1px solid #aaa;
}

.container_image {
  display: block;
  max-width: 100%;
  max-height: 100%;
  margin-left: auto;
  margin-right: auto;
}

.container2_image2 {
  width: 80px;
  height: 80px;
  object-fit: scale-down;
  border: 1px solid #aaa;
}
Without `object-fit: scale-down`:

<br>
<br>

<figure class="container">
  <img class="container_image" src="https://i.imgur.com/EQgexUd.jpg">
</figure>

<br>

<figure class="container">
  <img class="container_image" src="https://i.imgur.com/ptO8pGi.jpg">
</figure>

<br> Using `object-fit: scale-down`:

<br>
<br>

<figure>
  <img class="container2_image2" src="https://i.imgur.com/EQgexUd.jpg">
</figure>

<br>

<figure>
  <img class="container2_image2" src="https://i.imgur.com/ptO8pGi.jpg">
</figure>

gabrielmaldi
источник
2

Другое решение без фонового изображения и без контейнера (хотя должны быть известны максимальные размеры ограничивающей рамки):

img{
  max-height: 100px;
  max-width: 100px;
  width: auto;    /* These two are added only for clarity, */
  height: auto;   /* as the default is auto anyway */
}


Если требуется использование контейнера, тогда max-width и max-height могут быть установлены на 100%:

img {
    max-height: 100%;
    max-width: 100%;
    width: auto; /* These two are added only for clarity, */
    height: auto; /* as the default is auto anyway */
}

div.container {
    width: 100px;
    height: 100px;
}

Для этого у вас будет что-то вроде:

<table>
    <tr>
        <td>Lorem</td>
        <td>Ipsum<br />dolor</td>
        <td>
            <div class="container"><img src="image5.png" /></div>
        </td>
    </tr>
</table>
xerxeArt
источник
1

В этом примере изображение растягивается пропорционально до размера всего окна. Импровизация к приведенному выше правильному коду заключается в добавлении$( window ).resize(function(){});

function stretchImg(){
    $('div').each(function() {
      ($(this).height() > $(this).find('img').height()) 
        ? $(this).find('img').removeClass('fillwidth').addClass('fillheight')
        : '';
      ($(this).width() > $(this).find('img').width()) 
        ? $(this).find('img').removeClass('fillheight').addClass('fillwidth')
        : '';
    });
}
stretchImg();

$( window ).resize(function() {
    strechImg();
});

Есть два условия if. Первый продолжает проверять, меньше ли высота изображения, чем div, и применяет .fillheightкласс, а следующий проверяет ширину и применяет .fillwidthкласс. В обоих случаях другой класс удаляется с помощью.removeClass()

Вот CSS

.fillwidth { 
   width: 100%;
   max-width: none;
   height: auto; 
}
.fillheight { 
   height: 100vh;
   max-width: none;
   width: auto; 
}

Вы можете заменить 100vhна, 100%если хотите растянуть изображение с помощью div. В этом примере изображение растягивается пропорционально до размера всего окна.

Г-н JCRP
источник
OP специально попросил использовать только css.
Colt McCormack
0

Вы хотите масштабироваться вверх, но не вниз?

div {
    border: solid 1px green;
    width: 60px;
    height: 70px;
}

div img {
    width: 100%;
    height: 100%;
    min-height: 500px;
    min-width: 500px;
    outline: solid 1px red;
}

Однако это не фиксирует соотношение сторон.

ericosg
источник
5
Постарайтесь более четко выразить свои ожидания, прежде чем голосовать против чей-либо ответа. Особенно, если они ответили на ваш вопрос до того, как вы внесли изменения в свой вопрос.
Хан
2
Кроме того, постарайтесь быть более вежливым. Никто тебе не поможет, если ты так будешь говорить.
Миша Рейзлин 03
@Artimuz Мои извинения, если я пропустил вас, но мне показалось непонятным, что вы хотите сохранить соотношение сторон, поэтому я специально прокомментировал это. Кроме того, вы заметите, что я вставил фрагмент вашего кода из примеров. Считаю, выдерживая высоту: авто; сделает это за вас, если вы укажете ширину.
ericosg 03
0

Я использовал таблицу для центрирования изображения внутри коробки. Он сохраняет соотношение сторон и масштабирует изображение полностью внутри коробки. Если изображение меньше прямоугольника, то оно отображается в центре. В приведенном ниже коде используется поле шириной 40 пикселей и высотой 40 пикселей. (Не совсем уверен, насколько хорошо это работает, потому что я удалил его из другого более сложного кода и немного упростил)

CSS:

.SmallThumbnailContainer
{
    display: inline-block; position: relative;
    float: left;    
    width: 40px;
    height: 40px;
    border: 1px solid #ccc;
    margin: 0px; padding: 0px;
}
.SmallThumbnailContainer { width: 40px; margin: 0px 10px 0px 0px; } 
.SmallThumbnailContainer tr { height: 40px; text-align: center; }
.SmallThumbnailContainer tr td { vertical-align: middle; position: relative; width: 40px;  }
.SmallThumbnailContainer tr td img { overflow: hidden; max-height: 40px; max-width: 40px; vertical-align: middle; margin: -1px -1px 1px -1px; }

HTML:

<table class="SmallThumbnailContainer" cellpadding="0" cellspacing="0">
    <tr><td>
        <img src="thumbnail.jpg" alt="alternative text"/>
    </td></tr>
    </table>
Антти
источник
0

Самый чистый и простой способ сделать это:

Сначала немного CSS:

div.image-wrapper {
    height: 230px; /* Suggestive number; pick your own height as desired */
    position: relative;
    overflow: hidden; /* This will do the magic */
    width: 300px; /* Pick an appropriate width as desired, unless you already use a grid, in that case use 100% */
}
img {
    width: 100%;
    position: absolute;
    left: 0;
    top: 0;
    height: auto;
}

HTML:

<div class="image-wrapper">
  <img src="yourSource.jpg">
</div>

Это должно помочь!

Роберт Этхарт
источник
0

Мне это помогло:

.img-class {
  width: <img width>;
  height: <img height>;
  content: url('/path/to/img.png');
}

Затем в элементе (вы можете использовать javascript или медиа-запросы, чтобы добавить отзывчивость):

<div class='img-class' style='transform: scale(X);'></div>

Надеюсь это поможет!

bman93
источник
-3
.boundingbox {
    width: 400px;
    height: 500px;
    border: 2px solid #F63;
}
img{
    width:400px;
    max-height: 500px;
    height:auto;
}

Я редактирую свой ответ, чтобы подробнее объяснить свое решение, так как я проголосовал против.

Когда стили установлены, как показано выше в CSS, теперь следующий HTML-блок будет показывать изображение, всегда подходящее по ширине, и будет регулировать соотношение сторон высоты к ширине. Таким образом, изображение будет масштабироваться, чтобы соответствовать ограничивающей рамке, как указано в вопросе.

<div class="boundingbox"><img src="image.jpg"/></div>
zeeawan
источник
Этот ответ работает только тогда, когда ящик выше ширины.
XwipeoutX