Масштабне зображення для розміщення рамки


117

Чи є рішення, доступне лише для css, для масштабування зображення у обмежувальному полі (зберігаючи співвідношення сторін)? Це працює, якщо зображення більше, ніж контейнер:

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

Приклад:

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


Ви маєте на увазі висоту: 100% і ширину: 100%? чи є у вас бажаний вимір, якого ви хочете досягти? інакше ви також можете розтягнути зображення і змусити його також досягти цих розмірів.
mikevoermans

@mikevoermans Подивіться два мої перші приклади: я хочу розтягнути зображення, поки один з розмірів не стане 100%, а інший <= 100%
Thomas Guillory

@jacktheripper Збереження співвідношення сторін звичайно ...
Thomas Guillory

@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 для вмісту. Дивіться мою відповідь.
Томас Гіллорі

Ви абсолютно праві. Хоча зараз минуло півтора року, я редагував свою посаду.
Стефан Мюллер

4
Я б сказав, що це правильна відповідь на поставлене запитання, що є CSS для тега img. Це актуально, тому що семантично тег img є вмістом, зображення як тло діва не є. Хоча деякі обставини роблять це непрактичним (якщо ви не знаєте співвідношення зображення та контейнера), для інших це просто правильно. Дякую.
duncanwilcox

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

Щоб вирівняти поділку в центрі, ви можете використовувати цю варіацію:

.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: містити;
arxpoetica

3
Слід зазначити , що ви можете вводити URL - зображення з HTML: <div class=image style="background-image: url('/images/foo.jpg');"></div>. Усі інші стилі слід застосовувати за допомогою CSS.
Андрій Михайлов - lolmaus

14
Я б сказав, це жахливий підхід. Змінивши його на фонове зображення, ви видаляєте смислове значення зображення в HTML.
animuson

14
@animuson: Це все ще допомогло мені, оскільки я використовую HTML / CSS для друкованих звітів, і не міг дати шарлатан щодо семантики :)
Christian Wattengård

37

Ось таке хакізне рішення я знайшов:

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

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

На відміну від background-imageрішення, це також буде працювати з <video>елементами.

Інтерактивний приклад:


1
Я люблю це рішення. Він не тільки відповідає на питання (я знаю, що таке думка), він прекрасно працює у всіх сучасних браузерах, не звертаючись до Javascript!
ndm13

2
Я хотів би бачити загадку про це. У моєму тесті на розміщення img у контейнер
розміром 400x400

3
Гарна відповідь! @Yashua Вам потрібно додати, transform-origin: top leftщоб зупинити обрізку. / Zombie
XwipeoutX

Блискуча. Моє єдине занепокоєння - це можлива втрата якості зображення в погано зашифрованому браузері, але теоретично це повинно працювати нормально!
Codemonkey

Цікаво, але не працює на Chrome. Результати в обрізаному рядку зображення.
MattK

23

Сьогодні просто скажіть об’єкт-придатний: містити. Підтримка - це все, крім IE: http://caniuse.com/#feat=object-fit


3
IE має лише близько 16% частки ринку зараз на момент написання цього запису (12.12.2016 10:56) і продовжує зменшуватися, тому це найкраща відповідь для мене: D
Чжан

8
Не редагуйте відповіді інших людей, щоб виправляти інші речі, крім помилок друку чи зламаних посилань. Я б не сказав щось по-дитячому на кшталт "Є поліфіл для лайно-браузерів" у відповіді ТА, і я не ціную, що моя відповідь редагується, щоб вона виглядала так, як я це сказав. якщо ви хочете використовувати свої слова, поставте їх у власну відповідь.
Гленн Мейнард

Я б сказав, що проблема не IE, а Edge. За словами каніуси, для object-fitцього ще розробляються.
BairDev

Це має бути одним із найголосніших відповідей 2017 року і далі ... Згідно з посиланням на канюзу вище, 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;*/
}

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>


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 */
}


Якщо потрібно використовувати контейнер, то максимальну ширину та максимальну висоту можна встановити на 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>

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();
});

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

Ось CSS

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

Ви можете замінити 100vh, 100%якщо ви хочете розтягнути зображення у діві. Цей приклад розтягнути зображення пропорційно, щоб вмістити все вікно.


ОП спеціально попросила підходу, що стосується лише css.
Кольт Маккормак

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

Це, однак, не блокує співвідношення сторін.


5
Постарайтеся бути трохи більш зрозумілими з вашими очікуваннями, перш ніж чийсь голос чимось відповість. Особливо, коли вони відповіли на ваше запитання, перш ніж ви очистили своє питання правками.
Хан

2
Також намагайтеся бути ввічливішими. Ніхто не збирається вам допомогти, якщо ви так розмовляєте.
Міша Рейзлін

@Artimuz Мої вибачення, якщо я пропустив вас, але мені здалося незрозумілим, що ви хочете зберегти співвідношення сторін, саме тому я конкретно прокоментував це. Також ви помітите, що я вставив фрагмент вашого коду з прикладів. Я вважаю, що висота: авто; зробить це для вас, якщо вказати ширину.
ericosg

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>

Сподіваюся, це допомагає!


-3
.boundingbox {
    width: 400px;
    height: 500px;
    border: 2px solid #F63;
}
img{
    width:400px;
    max-height: 500px;
    height:auto;
}

Я редагую свою відповідь, щоб додатково пояснити свій солютон, коли я отримав подальний голос.

З урахуванням стилів, як показано вище в css, тепер наступний html div покаже, що зображення завжди відповідає ширині, і налаштує висоту співвідношення сторін до ширини. Таким чином зображення буде масштабуватися, щоб відповідати обмежувальній коробці, як задано в питанні.

<div class="boundingbox"><img src="image.jpg"/></div>

Ця відповідь працює лише тоді, коли ящик вище, ніж широкий.
XwipeoutX
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.