Глубокое погружение в объектную подгонку и фоновый размер в CSS
Опубликовано: 2022-03-10object-fit
и background-size
, когда мы можем их использовать и почему, а также некоторые практические примеры использования и рекомендации. Давайте погрузимся. Мы не всегда можем загрузить изображения разного размера для HTML-элемента. Если мы используем ширину и высоту, которые не пропорциональны соотношению сторон изображения, изображение может быть либо сжато, либо растянуто. Это нехорошо, и это можно решить либо с помощью object-fit
для элемента img
, либо с помощью background-size
.
Во-первых, давайте определим проблему. Рассмотрим следующий рисунок:

Почему это происходит?
Изображение будет иметь соотношение сторон, и браузер заполнит содержащее его поле этим изображением. Если соотношение сторон изображения отличается от указанных для него ширины и высоты, результатом будет либо сжатое, либо растянутое изображение.
Мы видим это на следующем рисунке:

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

Теперь, когда мы понимаем, как это работает, давайте рассмотрим, как это работает в браузере. ( Осторожно, спойлер: это проще! )
CSS object-fit
Свойство object-fit
определяет, как содержимое замененного элемента, такого как img
или video
, должно быть изменено, чтобы соответствовать его контейнеру. Значение по умолчанию для object-fit
— fill
, что может привести к сжатию или растяжению изображения.
Пройдемся по возможным значениям.
Возможные значения для object-fit
object-fit: contain
В этом случае размер изображения будет изменен в соответствии с соотношением сторон его контейнера. Если соотношение сторон изображения не соответствует соотношению сторон контейнера, оно будет помещено в почтовый ящик.

object-fit: contain
изображение будет либо помещено в леттербокс, либо соответствующим образом изменено его размер. (Большой превью) object-fit: cover
Здесь размер изображения также будет изменен, чтобы соответствовать соотношению сторон его контейнера, и если соотношение сторон изображения не соответствует соотношению сторон контейнера, оно будет обрезано по размеру.

object-fit: cover
изображение будет либо обрезано по размеру, либо соответствующим образом изменено. (Большой превью) object-fit: fill
При этом размер изображения будет изменен в соответствии с соотношением сторон его контейнера, и если соотношение сторон изображения не соответствует соотношению сторон контейнера, оно будет либо сжато, либо растянуто. Мы не хотим этого.

object-fit: fill
изображение будет соответственно сжато, растянуто или изменено в размере. (Большой превью) object-fit: none
В этом случае изображение вообще не будет изменяться в размере, ни растягиваться, ни сжиматься. Он работает как значение cover
, но не учитывает соотношение сторон своего контейнера.

object-fit: none
размер изображения не будет изменен, если его размеры не совпадают. (Большой превью) Помимо object-fit
у нас также есть свойство object-position
, которое отвечает за позиционирование изображения в его контейнере.
Возможные значения для object-position
Свойство object-position
работает аналогично свойству background-position
в CSS:

top
и bottom
ключевые слова также работают, когда соотношение сторон содержащего блока больше по вертикали:

object-position: top
(слева) и object-position: bottom
(справа). (Большой превью) background-size
CSS
С background-size
первое отличие состоит в том, что мы имеем дело с фоном, а не с элементом HTML ( img
).
Возможные значения для background-size
Возможные значения для background-size
: auto
, contain
и cover
.
background-size: auto
С auto
изображение останется в размере по умолчанию:

background-size: cover
Здесь размер изображения будет изменен, чтобы поместиться в контейнере. Если соотношения сторон не совпадают, изображение будет замаскировано по размеру.

background-size: cover
обязательно учитывайте соотношение сторон изображения. (Большой превью) background-size: contain
В этом случае размер изображения будет изменен, чтобы поместиться в контейнере. Если соотношение сторон отключено, изображение будет иметь леттербокс, как показано в следующем примере:


background-size: contain
contains изменяет размер изображения, чтобы оно поместилось в контейнере. (Большой превью) Что касается background-position
, это похоже на то, как работает object-position
. Единственное отличие состоит в том, что позиция object-position
по умолчанию отличается от background-position
.
Когда не следует использовать размер object-fit
или background-size
Если элементу или изображению задана фиксированная высота и к нему применяется background-size: cover
или object-fit: cover
, в какой-то момент изображение будет слишком широким, что приведет к потере важных деталей, которые могут повлиять на качество изображения. пользователь воспринимает изображение.
Рассмотрим следующий пример, в котором изображению задана фиксированная высота:
.card__thumb { height: 220px; }

Если контейнер карты слишком широкий, это приведет к тому, что мы видим справа (слишком широкое изображение). Это потому, что мы не указываем соотношение сторон.
Для этого есть только одно из двух исправлений. Первый заключается в использовании хака заполнения для создания внутреннего соотношения.
.card__thumb { position: relative; padding-bottom: 75%; height: 0; } .card__thumb img { position: absolute; left: 0; top: 0; width: 100%; height: 100%; object-fit: cover; }
Второе исправление заключается в использовании нового CSS aspect-ratio
. Используя его, мы можем сделать следующее:
.card__thumb img { aspect-ratio: 4 / 3; }
Примечание . Я уже подробно писал о свойстве « aspect-ratio
» на случай, если вы захотите узнать о нем: «Давайте узнаем о соотношении сторон в CSS».
Варианты использования и примеры
Аватары пользователей
Идеальный вариант использования object-fit: cover
— это пользовательские аватары. Соотношение сторон, разрешенное для аватара, часто квадратное. Помещение изображения в квадратный контейнер может привести к искажению изображения.

object-fit
и с object-fit: cover
. (Большой превью) .c-avatar { object-fit: cover; }
Список логотипов
Список клиентов бизнеса имеет важное значение. Мы будем часто использовать логотипы для этой цели. Поскольку логотипы будут иметь разные размеры, нам нужен способ изменить их размер, не искажая их.
К счастью, object-fit: contain
хорошее решение для этого.
.logo__img { width: 150px; height: 80px; object-fit: contain; }

object-fit: contain
может помочь нам изменить размер логотипов клиентов, не искажая их. (Большой превью)Миниатюра статьи
Это очень распространенный вариант использования. Контейнер для миниатюры статьи может не всегда содержать изображение с одинаковым соотношением сторон. Эта проблема должна быть исправлена в первую очередь системой управления контентом (CMS), но это не всегда так.
.article__thumb { object-fit: cover; }

object-fit: cover
. (Большой превью)Предыстория героя
В этом случае решение об использовании элемента img
или фона CSS будет зависеть от следующего:
- Важен ли имидж? Если CSS по какой-то причине отключен, хотим ли мы, чтобы пользователь видел изображение?
- Или цель изображения просто декоративная?
Основываясь на нашем ответе, мы можем решить, какую функцию использовать. Если изображение важно :

<section class="hero"> <img class="hero__thumb" src="thumb.jpg" alt="" /> </section>
.hero { position: relative; } .hero__thumb { position: absolute; left: 0; top: 0; width: 100%; height: 100%; object-fit: cover; }
Если изображение является декоративным , мы можем использовать background-image
:
.hero { position: relative; background-image: linear-gradient(to top, #a34242, rgba(0,0,0,0), url("thumb.jpg"); background-repeat: no-repeat; background-size: cover; }
В этом случае CSS короче. Убедитесь, что любой текст, размещенный поверх изображения, читаем и доступен.
Добавление фона к изображению с помощью object-fit: contain
Знаете ли вы, что вы можете добавить цвет фона в img
? Мы выиграем от этого, если также будем использовать object-fit: contain
.
В приведенном ниже примере у нас есть сетка изображений. Когда соотношения сторон изображения и контейнера различаются, отображается цвет фона.
img { object-fit: contain; background-color: #def4fd; }

object-fit: contain
, чтобы добавить фоновый цвет к изображению. (Большой превью)Видеоэлемент
Вам когда-нибудь требовалось video
в качестве фона? Если это так, то вы, вероятно, хотели, чтобы он занимал всю ширину и высоту своего родителя.
.hero { position: relative; background-color: #def4fd; } .hero__video { position: aboslute; left: 0; top: 0; width: 100%; height: 100%; }

object-fit
по умолчанию для элемента video
contain
. Как вы можете видеть здесь, видео не закрывает фон героя, хотя у него есть position: absolute
, width: 100%
и height: 100%
. (Большой превью) Чтобы он полностью покрывал ширину и высоту своего родителя, нам нужно переопределить значение object-fit
по умолчанию:
.hero__video { /* other styles */ object-fit: cover; }

Заключение
Как мы видели, и object-fit
и background-size
очень полезны для обработки различных соотношений сторон изображения. У нас не всегда будет контроль над установкой идеальных размеров для каждого изображения, и именно здесь сияют эти две функции CSS.
Дружеское напоминание о последствиях выбора между элементом img
и фоном CSS для доступности: если изображение чисто декоративное, выберите фон CSS. В противном случае больше подходит img
.
Я надеюсь, что вы нашли эту статью полезной. Спасибо за чтение.