Глубокое погружение в объектную подгонку и фоновый размер в CSS

Опубликовано: 2022-03-10
Краткое резюме ↬ В этой статье мы рассмотрим, как работают object-fit и background-size , когда мы можем их использовать и почему, а также некоторые практические примеры использования и рекомендации. Давайте погрузимся.

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

Во-первых, давайте определим проблему. Рассмотрим следующий рисунок:

Сравнение красивого фото и сжатого изображения
Красивая фотография, которая сжимается при использовании в карточном компоненте. (Большой превью)

Почему это происходит?

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

Мы видим это на следующем рисунке:

Сравнение красивой фотографии и растянутого изображения
Соотношение сторон изображения отличается от содержащего его поля, и изображение растягивается. (Большой превью)

Решение

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

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

Теперь, когда мы понимаем, как это работает, давайте рассмотрим, как это работает в браузере. ( Осторожно, спойлер: это проще! )

CSS object-fit

Свойство object-fit определяет, как содержимое замененного элемента, такого как img или video , должно быть изменено, чтобы соответствовать его контейнеру. Значение по умолчанию для object-fitfill , что может привести к сжатию или растяжению изображения.

Пройдемся по возможным значениям.

Еще после прыжка! Продолжить чтение ниже ↓

Возможные значения для 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:

положение объекта по центру, слева, справа
В большинстве случаев используется значение по умолчанию (например, `center` или `50% 50%`). (Большой превью)

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; }
Список логотипов: Airbnb, Domino’s Pizza, Apple Pay, Amazon
Использование 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: содержит
Мы можем использовать 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 .

Я надеюсь, что вы нашли эту статью полезной. Спасибо за чтение.