CSS принудительно изменяет размер изображения и сохраняет соотношение сторон


577

Я работаю с изображениями, и я столкнулся с проблемой с соотношением сторон.

<img src="big_image.jpg" width="900" height="600" alt="" />

Как видите, heightи widthуже указаны. Я добавил правило CSS для изображений:

img {
  max-width:500px;
}

Но за big_image.jpg, я получаю width=500и height=600. Как я могу настроить изображения для изменения размера, сохраняя при этом их пропорции.

Ответы:


775

img {
  display: block;
  max-width:230px;
  max-height:95px;
  width: auto;
  height: auto;
}
<p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
<img width="400" height="400" src="http://i.stack.imgur.com/aEEkn.png">

Это уменьшит изображение, если оно слишком велико для указанной области (как недостаток, оно не увеличит изображение).


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

7
Кажется, что дисплей: блок больше не нужен.
Актимель

3
Обратите внимание, что вопрос был о <img>том, что само по себе включает в себя ширину и высоту, и я думаю, что это означает, что вам нужно использовать, !importantчтобы обойти информацию о ширине / высоте тега.
Алексис Уилке

18
@AlexisWilke CSS-правила переопределяют атрибуты HTML. !importantне нужен
Jargs

5
Использование его в Chrome, не работает для меня, даже с! Важным
Рэй

266

Я довольно тяжело боролся с этой проблемой и в итоге пришел к такому простому решению:

object-fit: cover;
width: 100%;
height: 250px;

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

Приветствия.


44
object-fitэто фантастика, отличный совет! Есть несколько прекрасных библиотек polyfill, если кто-то интересуется совместимостью с IE.
мягко

7
Прекрасно, имейте в виду, что это не работает для IE, хотя
guival

1
Не работает в SAMSUNG Signage Display WebApps.
MAR

3
Лучшее доступное решение
Синтия Санчес

10
Вы также можете использовать object-fit: containи указать ширину или высоту!
Брофер

236

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

Все изображения имеют родительский контейнер с фиксированной шириной только для демонстрационных целей . В производстве это будет ширина родительской рамки.

Лучшая практика (2018):

Это решение говорит браузеру визуализировать изображение с максимально доступной шириной и регулировать высоту в процентах от этой ширины.

.parent {
  width: 100px;
}

img {
  display: block;
  width: 100%;
  height: auto;
}
<p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
<div class="parent">
  <img width="400" height="400" src="https://placehold.it/400x400">
</div>

Любимое решение:

С помощью более изящного решения вы сможете обрезать изображение независимо от его размера и добавить цвет фона для компенсации обрезки.

.parent {
  width: 100px;
}

.container {
  display: block;
  width: 100%;
  height: auto;
  position: relative;
  overflow: hidden;
  padding: 34.37% 0 0 0; /* 34.37% = 100 / (w / h) = 100 / (640 / 220) */
}

.container img {
  display: block;
  max-width: 100%;
  max-height: 100%;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}
<p>This image is originally 640x220, but should get resized by the CSS:</p>
<div class="parent">
  <div class="container">
    <img width="640" height="220" src="https://placehold.it/640x220">
  </div>
</div>

Для строки, задающей отступы, необходимо рассчитать соотношение сторон изображения, например:

640px (w) = 100%
220px (h) = ?

640/220 = 2.909
100/2.909 = 34.37%

Итак, верхний отступ = 34,37%.


1
Это работает, но должно быть max-width: 100% вместо ширины в большинстве случаев.
Dudeist

Я не думаю !important, что здесь нужно.
Flimm

1
С родителем, установленным на 100px. Как это будет работать в ответ?
Реми

@Remi это для демонстрационных целей. Я добавил пояснение к началу ответа.
Aternus

@Flimm раньше использовался для проблем совместимости, в 2016 году он больше не нужен.
Aternus

64

Свойство background-size имеет значение ie> = 9, но если вас это устраивает, вы можете использовать div с помощью background-imageи установить background-size: contain:

div.image{
    background-image: url("your/url/here");
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
}

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

Этот подход отличается от ответа setecs, при этом область изображения будет постоянной и задана вами (оставляя пустые места по горизонтали или по вертикали в зависимости от размера div и соотношения сторон изображения), в то время как ответ setecs даст вам коробку, которая точно размер масштабированного изображения (без пробелов).

Изменить: Согласно документации MDN background-size вы можете смоделировать свойство background-size в IE8, используя собственное объявление фильтра:

Хотя Internet Explorer 8 не поддерживает свойство background-size, некоторые его функции можно эмулировать с помощью нестандартной функции -ms-filter:

-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='path_relative_to_the_HTML_file', sizingMethod='scale')";

2
наконец, единственное решение CSS для максимизации изображения при сохранении его пропорций, спасибо. К счастью, IE до 9 становится все более неважным.
человечество и

2
Отличное решение, спасибо! Также обратите внимание, что вы можете заменить «содержать» на «обложка», если вы хотите полностью заполнить div и обрезать лишние пиксели, которые не соответствуют соотношению
mbritto

Это должен быть правильный ответ. Я люблю это решение. Он сохраняет ваши пропорции и легко понять.
skolind

1
Хотя это правильный программный ответ, если изображение «имеет значение», у вас нет атрибутов img, поэтому вы убиваете SEO.
fat_mike

Большой! Это было единственное из этих решений, которое работало как с портретными и альбомными изображениями, так и с портретными и альбомными контейнерами изображения (например, изменяющимися в зависимости от размера окна) во всех 4 комбинациях и, кроме того, в IE11, что, казалось, было довольно требование. Спасибо!
cupiqi09

53

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

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

.img {
   object-fit: contain;
   max-width: 100%;
   max-height: 100%;
   width: auto;
   height: auto;
}

object-fitу меня работает работает ли он во всех браузерах?
Муртуза Забуавала,

Есть .imgкласс на родителя или изображение? Не могли бы вы сделать jsfiddle с примером для портретных и пейзажных изображений?
Дизайн Адриана

19

Удалите свойство «высота».

<img src="big_image.jpg" width="900" alt=""/>

Указывая оба, вы меняете соотношение сторон изображения. Простая установка изменит размер, но сохранит соотношение сторон.

По желанию, чтобы ограничить превышения:

<img src="big_image.jpg" width="900" alt="" style="max-width:500px; height:auto; max-height:600px;"/>

я не могу сделать это со всеми изображениями - во многих файлах HTML уже размещено много изображений
moonvader

2
Хорошо. попробуйте img {max-width: 500px; высота: авто; максимальная высота: 600 пикселей;}
эль Чувак

1
Полезная информация, такая как этот комментарий, должна быть добавлена ​​в ваш пост. Таким образом мы сразу увидим, что вы придумали.
Брэм Ванрой

2
Недостатком пропуска heightатрибута в imgтеге является то, что браузер не может рассчитать, сколько места займет изображение, прежде чем загрузить изображение. Это замедляет рендеринг страницы и может привести к еще большему «скачку».
Flimm

11

Просто добавьте это к вашему CSS, он будет автоматически уменьшаться и расширяться при сохранении исходного соотношения.

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

2
Это тот же ответ, что и ответ setec , за исключением использования 100%вместо определенного значения в пикселях.
Flimm

5
display: block;не нужно
Flimm

Это прекрасно и работает с изображениями любого размера и пропорции
Le Droid

8

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

Поэтому мы вынуждены либо указывать widthи heightпредотвращать «скачки» страниц при загрузке изображений, либо использовать max-widthи не указывать размеры для изображений.

Указывать просто width(без height) обычно не имеет особого смысла, но вы можете попытаться переопределить heightатрибут HTML, добавив правило, подобное IMG {height: auto; }вашей таблице стилей.

Смотрите также связанную ошибку Firefox 392261 .


спасибо, это работает в современных версиях IE, Opera, FF и Chrome. Мне нужно время, чтобы проверить это с другими браузерами.
Moonvader

7
Не используйте !importantв CSS. Это взлом, который в конечном итоге будет преследовать вас.
Automatico

1
Вам даже не нужно !importantздесь.
Flimm

8

Вот решение:

img {
   width: 100%;
   height: auto;
   object-fit: cover;
}

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


5

Установите класс CSS вашего тега контейнера изображений image-class:

<div class="image-full"></div>

и добавьте это вам свою таблицу стилей CSS.

.image-full {
    background: url(...some image...) no-repeat;
    background-size: cover;
    background-position: center center;
}

5

Чтобы сохранить отзывчивое изображение при сохранении определенного соотношения сторон, вы можете сделать следующее:

HTML:

<div class="ratio2-1">
   <img src="../image.png" alt="image">
</div>

И SCSS:

.ratio2-1 {
  overflow: hidden;
  position: relative;

  &:before {
    content: '';
    display: block;
    padding-top: 50%; // ratio 2:1
  }

  img {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
  }
}

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

Спасибо @Kseso по адресу http://codepen.io/Kseso/pen/bfdhg . Проверьте этот URL для большего количества отношений и рабочего примера.


Мне нравится это, поскольку это работает с кругами / border-radius. Но, к сожалению, он обрезает изображение и не очень хорошо делает границы для изображения в div, насколько я пытался.
Джейк

4

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

img{
    width: 200px;
    height: auto;
    object-fit: contain; /* Fit logo in the image size */
        -o-object-fit: contain; /* Fit logo fro opera browser */
    object-position: top; /* Set logo position */
        -o-object-position: top; /* Logo position for opera browser */
    }
<img src="http://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.png" alt="Logo">


4

https://jsfiddle.net/sot2qgj6/3/

Вот ответ, если вы хотите поместить изображение с фиксированным процентом ширины , но не с фиксированным пикселем ширины .

И это будет полезно при работе с экранами разного размера .

Трюки

  1. Используя, padding-topчтобы установить высоту от ширины.
  2. Использование, position: absoluteчтобы поместить изображение в отступы.
  3. Использование, max-height and max-widthчтобы убедиться, что изображение не будет над родительским элементом.
  4. используя display:block and margin: autoдля центрирования изображения.

Я также комментирую большинство хитростей внутри скрипки.


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

простой CSS с помощью фона http://jsfiddle.net/4660s79h/2/

фоновое изображение со словом сверху http://jsfiddle.net/4660s79h/1/

концепция использования абсолютного положения отсюда http://www.w3schools.com/howto/howto_css_aspect_ratio.asp


Это не работает, если «высота и ширина уже заданы», как упоминается в исходном вопросе. Есть моменты, когда вы хотите увеличить ширину и высоту, а затем увеличить / уменьшить изображение в соответствии с соотношением сторон.
Дизайн Адриана

3

Вы можете использовать это:

img { 
    width: 500px; 
    height: 600px; 
    object-fit: contain; 
    position: relative; 
    top: 50%; 
    transform: translateY(-50%); 
}

2

Вы можете создать div следующим образом:

<div class="image" style="background-image:url('/to/your/image')"></div>

И используйте этот CSS для стилизации:

height: 100%;
width: 100%;
background-position: center center;
background-repeat: no-repeat;
background-size: contain; // this can also be cover

Это растянет div до 100% ширины его родителя, но не сохранит пропорции изображения.
Дэвид Болл

Вы пробовали это? Я получил это работа jsfiddle.net/zuysj22w . Вы можете показать свой случай? @DavidBall
Чун Ян

Это аналогичное решение ответа Гофмана .
Flimm

2

Я бы посоветовал для адаптивного подхода лучше всего использовать единицы измерения Viewport и атрибуты min / max следующим образом:

img{
  display: block;
  width: 12vw;
  height:12vw;
  max-width:100%;
  min-width:100px;
  min-height:100px;
  object-fit:contain;
}

1

Это уменьшит изображение, если оно слишком велико для указанной области (как недостаток, оно не увеличит изображение).

Решение от setec отлично подходит для «Shrink to Fit» в автоматическом режиме. Но, чтобы оптимально РАСШИРЯТЬСЯ, чтобы уместиться в «автоматическом» режиме, вам нужно сначала поместить полученное изображение во временный идентификатор. Проверьте, можно ли увеличить его по высоте или ширине (в зависимости от соотношения сторон относительно соотношения сторон: ваш дисплейный блок),

$(".temp_image").attr("src","str.jpg" ).load(function() { 
    // callback to get actual size of received image 

    // define to expand image in Height 
    if(($(".temp_image").height() / $(".temp_image").width()) > display_aspect_ratio ) {
        $(".image").css('height', max_height_of_box);
        $(".image").css('width',' auto');
    } else { 
        // define to expand image in Width
        $(".image").css('width' ,max_width_of_box);
        $(".image").css('height','auto');
    }
    //Finally put the image to Completely Fill the display area while maintaining aspect ratio.
    $(".image").attr("src","str.jpg");
});

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


Хотя в посте с вопросом ничего не сказано, я думаю, что OP явно подразумевал, что он / она ищет решение только для CSS.
Flimm

0

img {
  max-width: 80px; /* Also works with percentage value like 100% */
  height: auto;
}
<p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
<img width="400" height="400" src="https://i.stack.imgur.com/aEEkn.png">

<p>Let's say the author of the HTML deliberately wants
  the height to be half the value of the width,
  this CSS will ignore the HTML author's wishes, which may or may not be what you want:
</p>
<img width="400" height="200" src="https://i.stack.imgur.com/aEEkn.png">


0

Как насчет использования псевдоэлемента для вертикального выравнивания? Этот код меньше для карусели, но я думаю, он работает на каждом контейнере фиксированного размера. Он сохранит соотношение сторон и вставит серо-темные полосы сверху / снизу или слева / для записи для кратчайшего измерения. В то же время изображение центрируется по горизонтали с помощью выравнивания текста и по вертикали с помощью псевдоэлемента.

    > li {
      float: left;
      overflow: hidden;
      background-color: @gray-dark;
      text-align: center;

      > a img,
      > img {
        display: inline-block;
        max-height: 100%;
        max-width: 100%;
        width: auto;
        height: auto;
        margin: auto;
        text-align: center;
      }

      // Add pseudo element for vertical alignment of inline (img)
      &:before {
        content: "";
        height: 100%;
        display: inline-block;
        vertical-align: middle;
      }
    }

0

Полноэкранная презентация:

img[data-attribute] {height: 100vh;}

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


-1

Я думаю, наконец, что это лучшее решение, легкое и простое :

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

1
Не могли бы вы вкратце объяснить, почему это решение помогает? (Достаточно одного предложения.)
Aenadon

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