Подробное рассмотрение object-fit и background-size в CSS
Мы не всегда можем загрузить изображения разного размера в элемент HTML. Если мы используем ширину и высоту, которые не пропорциональны соотношению сторон изображения, изображение может быть сжато или растянуто. Это плохо, и это можно решить либо с помощью object-fit элемента img, либо с помощью background-size.
Во-первых, давайте определимся с проблемой. Рассмотрим следующий рисунок:
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Почему это происходит?
Содержание статьи:
Изображение будет иметь соотношение сторон, и браузер заполнит соответствующее поле этим изображением. Если соотношение сторон изображения отличается от указанной для него ширины и высоты, то результатом будет либо сжатое, либо растянутое изображение.
Мы видим это на следующем рисунке:
Решение
Нам не всегда нужно добавлять изображение другого размера, если соотношение сторон изображения не совпадает с шириной и высотой содержащего элемента. Прежде чем погрузиться в решения CSS, я хочу показать вам, как мы это делали в приложениях для редактирования фотографий:
Теперь, когда мы понимаем, как это работает, давайте разберемся, как это работает в браузере.
Свойство CSS object-fit
Свойство object-fit определяет, как содержание элемента (такое как img или video) должно быть изменено, чтобы соответствовать размеру его контейнера. Значение по умолчанию для object-fit равно fill, что может привести к сжатию или растягиванию изображения.
Давайте рассмотрим возможные значения для object-fit.
object-fit: contain
В этом случае размер изображения будет изменен в соответствии с соотношением сторон его контейнера.
object-fit: cover
Размер изображения будет изменен, чтобы соответствовать соотношению сторон его контейнера, и если соотношение сторон изображения не совпадает с соотношением сторон контейнера, изображение будет обрезано по размеру контейнера.
object-fit: fill
При этом размер изображения будет изменен в соответствии с соотношением сторон его контейнера, и если соотношение сторон изображения не соответствует соотношению сторон контейнера, оно будет либо сжато, либо растянуто. Мы этого не хотим.
object-fit: none
В этом случае изображение вообще не будет изменено, ни растянуто, ни сжато. Оbject-fit:none работает как значение cover, но не соблюдает соотношение сторон своего контейнера.
Помимо object-fit, у нас также есть свойство object-position, которое отвечает за размещение изображения в его контейнере.
Возможные значения для object-position
Свойство object-position работает аналогично CSS свойству background-position.
Ключевые слова top и bottom также работают, когда превышается вертикальное соотношение сторон содержащего контейнера.
CSS background-size
Первое отличие background-size заключается в том, что мы имеем дело с фоном, а не с элементом img как в HTML.
Возможные занчения background-size
Возможными значениями background-size являются auto, contain и cover.
background-size: auto
С auto, изображение сохранит размер по умолчанию.
background-size: cover
Изображение будет изменено так, чтобы оно поместилось в контейнере. Если соотношения сторон не совпадают, изображение будет обрезано по размеру.
background-size:contain
В этом случае размер изображения будет изменен, чтобы оно поместилось в контейнер.
Что касается background-position, то оно похоже на работу object-position. Единственное отличие состоит в том, что позиция по умолчанию для них разная.
Когда не нужно использовать object-fit или background-size
Если элемент или изображение имеет фиксированную высоту и имеет либо background-size:cover либо object-fit:cover, возможен результат, в котором изображение будет слишком широким, таким образом, теряя важные детали, которые могут повлиять на восприятие пользователем.
Рассмотрим следующий пример, в котором изображению присвоена фиксированная высота:
CSS .card__thumb { height: 220px; }
123 | .card__thumb { height: 220px;} |
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Если контейнер карты слишком широк, это приведет к тому, что мы видим справа (слишком широкое изображение). Это потому, что мы не указываем соотношение сторон. Есть два возможных решения. Первое — использовать метод заполнения для создания внутреннего соотношения.
CSS .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; }
1234567891011121314 | .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. Мы можем сделать следующее:
CSS .card__thumb img { aspect-ratio: 4 / 3; }
123 | .card__thumb img { aspect-ratio: 4 / 3;} |
Случаи использования и примеры
Аватарки пользователей
Идеальный вариант использования object-fit:cover — аватарки пользователей. Соотношение сторон, разрешенное для аватарки, часто бывает квадратным. Размещение изображения в квадратном контейнере может исказить изображение.
CSS .c-avatar { object-fit: cover; }
123 | .c-avatar { object-fit: cover;} |
Список логотипов
Мы часто используем логотипы для перечисления клиентов. Поскольку логотипы имеют разные размеры, нам нужен способ изменить их, не искажая. К счастью, хорошее решение для этого object-fit:contain.
CSS .logo__img { width: 150px; height: 80px; object-fit: contain; }
12345 | .logo__img { width: 150px; height: 80px; object-fit: contain;} |
Миниатюры статей
Это очень распространенный вариант использования. Контейнер для миниатюры статьи не всегда может содержать изображение с одинаковым соотношением сторон. Эта проблема должна быть исправлена в первую очередь системой управления контентом (CMS), но не всегда такое возможно.
CSS .article__thumb { object-fit: cover; }
123 | .article__thumb { object-fit: cover;} |
HERO-фон
В этом случае решение о том, использовать ли элемент img или фон CSS, будет зависеть от следующего:
Изображение важно? Если по какой-то причине CSS отключен, хотим ли мы, чтобы пользователь видел изображение?
Или цель изображения чисто декоративная?
Основываясь на ответе, мы можем решить, какую функцию использовать. Если изображение важно:
<section class=”hero”> <img class=”hero__thumb” src=”thumb.jpg” alt=”” /> </section>
123 | <section class=”hero”> <img class=”hero__thumb” src=”thumb.jpg” alt=”” /></section> |
CSS .hero { position: relative; } .hero__thumb { position: absolute; left: 0; top: 0; width: 100%; height: 100%; object-fit: cover; }
123456789101112 | .hero { position: relative;} .hero__thumb { position: absolute; left: 0; top: 0; width: 100%; height: 100%; object-fit: cover; } |
Если изображение декоративное, мы можем использовать background-image:
CSS .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; }
123456 | .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.
В приведенном ниже примере у нас есть сетка изображений. Если соотношения сторон изображения и контейнера различны, появится цвет фона.
CSS img { object-fit: contain; background-color: #def4fd; }
1234 | img { object-fit: contain; background-color: #def4fd;} |
Видеоэлемент
Вам когда-нибудь был нужен элемент video в качестве фона? Если это так, то вы, вероятно, хотели бы, чтобы он занимал всю ширину и высоту своего родителя.
CSS .hero { position: relative; background-color: #def4fd; } .hero__video { position: aboslute; left: 0; top: 0; width: 100%; height: 100%; }
123456789101112 | .hero { position: relative; background-color: #def4fd;} .hero__video { position: aboslute; left: 0; top: 0; width: 100%; height: 100%;} |
Чтобы элемент video полностью покрыл ширину и высоту своего родителя, нам нужно переопределить значение по умолчанию для object-fit:
CSS .hero__video { /* other styles */ object-fit: cover; }
1234 | .hero__video { /* other styles */ object-fit: cover;} |
Заключение
Как видите, и object-fit и background-size очень полезны для обработки различных соотношений сторон изображения. У нас не всегда будет контроль над установкой идеальных размеров для каждого изображения, и именно в этом проявляются эти две функции CSS.
Дружественный совет для выбора между элементом img и фоном CSS: если изображение чисто декоративное, выберите фон CSS. В противном случае более подходит img. Надеюсь, вы нашли эту статью полезной. Спасибо за чтение.
Автор: Ahmad Shadeed
Источник: webformyself.com