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

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

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

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

object-fit: cover
В этом случае размер изображения также будет изменен в соответствии с соотношением сторон контейнера, и если соотношение сторон изображения не соответствует размеру контейнера, оно будет обрезано по размеру.

object-fit: fill
При этом значении размер изображения будет изменен в соответствии с соотношением сторон контейнера, и если соотношение сторон изображения не соответствует размеру контейнера, оно будет либо сжато, либо растянуто. Но мы этого не хотим.

object-fit: none
В этом случае размер изображения вообще не будет изменен, ни растянут, ни сжат. Это значение работает так же, как значение cover, но при этом не учитывается соотношение сторон контейнера.

Кроме свойства object-fit, еще есть свойство object-position, которое отвечает за положение изображения внутри контейнера.
Возможные значения свойства object-position
Свойство object-position работает аналогично свойству CSS background-position:

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

Свойство background-size
Основное отличие свойства background-size заключается в том, что мы имеем дело с фоном, а не с HTML элементом (img).
Возможные значения background-size
Свойство background-size может принимать значения auto, contain и cover.
background-size: auto
При значении auto изображение сохраняет свой оригинальный размер:

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

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

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

Если контейнер слишком широк, это приведет к результату, который мы видим на рисунке справа (изображение слишком широкое). Это происходит потому, что мы не задаем соотношение сторон.
Решить эту проблему можно только двумя способами. Первый - это использовать трюк под названием "padding hack", чтобы создать внутреннее соотношение сторон.
.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;
}
Случаи использования и примеры
Аватары пользователей
Идеальный вариант использования object-fit: cover - это аватары пользователей. Обычно соотношение сторон, допустимое для аватара, квадратное. Размещение изображения в квадратном контейнере может исказить изображение.

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

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

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

<section class="hero">
<img class="hero__thumb" src="//msiter.ru/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;
}

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

Чтобы видео полностью заполнило родительский элемент, нам нужно переопределить значение по умолчанию у object-fit:
.hero__video {
/* другие стили */
object-fit: cover;
}
Заключение
Как вы, наверное, убедились, свойства object-fit и background-size очень полезны для обработки изображений с различными соотношениями сторон. Мы не всегда можем контролировать настройку идеальных размеров для каждого изображения, и именно здесь эти два CSS свойства незаменимы.
И еще стоит дружески напомнить о выборе между элементом img и фоном CSS: Если изображение является чисто декоративным, выбирайте фон CSS. В противном случае более подходит элемент img.
Надеемся, что данная статья была вам полезна. Спасибо, что дочитали ее до конца.