От автора: в этой статье мы рассмотрим, как работают object-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: cover
Размер изображения будет изменен, чтобы соответствовать соотношению сторон его контейнера, и если соотношение сторон изображения не совпадает с соотношением сторон контейнера, изображение будет обрезано по размеру контейнера.
При использовании object-fit: cover изображение будет либо обрезано по размеру контейнера, либо, соответствующим образом, изменен его размер
object-fit: fill
При этом размер изображения будет изменен в соответствии с соотношением сторон его контейнера, и если соотношение сторон изображения не соответствует соотношению сторон контейнера, оно будет либо сжато, либо растянуто. Мы этого не хотим.
При использовании object-fit: fill изображение будет соответственно сжато, растянуто или изменено в размере
object-fit: none
В этом случае изображение вообще не будет изменено, ни растянуто, ни сжато. Оbject-fit:none работает как значение cover, но не соблюдает соотношение сторон своего контейнера.
При использовании object-fit:none изображение не будет изменено, если его размеры не совпадают
Помимо object-fit, у нас также есть свойство object-position, которое отвечает за размещение изображения в его контейнере.
Возможные значения для object-position
Свойство object-position работает аналогично CSS свойству background-position.
В большинстве случаев используется значение по умолчанию (например, «center» или «50% 50%»)
Ключевые слова top и bottom также работают, когда превышается вертикальное соотношение сторон содержащего контейнера.
Сравнение object-position: top(слева) и object-position:bottom(справа)
CSS background-size
Первое отличие background-size заключается в том, что мы имеем дело с фоном, а не с элементом img как в HTML.
Возможные занчения background-size
Возможными значениями background-size являются auto, contain и cover.
background-size: auto
С auto, изображение сохранит размер по умолчанию.
Имейте в виду, что размер по умолчанию может иногда приводить к размытому изображению (если оно слишком маленькое)
background-size: cover
Изображение будет изменено так, чтобы оно поместилось в контейнере. Если соотношения сторон не совпадают, изображение будет обрезано по размеру.
При использовании background-size:cover обязательно учитывайте соотношение сторон изображения
background-size:contain
В этом случае размер изображения будет изменен, чтобы оно поместилось в контейнер.
background-size: contain изменяет размер изображения в соответствии с размером контейнера
Что касается background-position, то оно похоже на работу object-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; }
Случаи использования и примеры
Аватарки пользователей
Идеальный вариант использования 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
HERO-фон
В этом случае решение о том, использовать ли элемент 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 равно contain. Как вы можете видеть, видео не покрывает hero-фон, даже если у него установлены position:absolute, width: 100% и height: 100%
Чтобы элемент video полностью покрыл ширину и высоту своего родителя, нам нужно переопределить значение по умолчанию для object-fit:
.hero__video { /* other styles */ object-fit: cover; }
Теперь видео покрывает всю ширину и высоту своего родителя
Заключение
Как видите, и object-fit и background-size очень полезны для обработки различных соотношений сторон изображения. У нас не всегда будет контроль над установкой идеальных размеров для каждого изображения, и именно в этом проявляются эти две функции CSS.
Дружественный совет для выбора между элементом img и фоном CSS: если изображение чисто декоративное, выберите фон CSS. В противном случае более подходит img. Надеюсь, вы нашли эту статью полезной. Спасибо за чтение.
Автор: Ahmad Shadeed
Источник: www.smashingmagazine.com
Редакция: Команда webformyself.
Читайте нас в Telegram, VK, Яндекс.Дзен