Свойство CSS-пропорций

Свойство CSS, помогающее поддерживать отступы в адаптивных макетах.

Соотношение сторон

Browser Support

  • Chrome: 88.
  • Край: 88.
  • Firefox: 89.
  • Сафари: 15.

Source

Соотношение сторон чаще всего выражается двумя целыми числами и двоеточием в формате: ширина:высота, или x:y. Наиболее распространенные соотношения сторон для фотографии — 4:3 и 3:2, в то время как для видеосъемки и более современных потребительских камер обычно используется соотношение сторон 16:9.

Два изображения с одинаковым соотношением сторон. Одно размером 634 x 951 пикселей, другое — 200 x 300 пикселей. Оба имеют соотношение сторон 2:3.
Два изображения с одинаковым соотношением сторон. Одно размером 634 x 951 пикселей, другое — 200 x 300 пикселей. Оба имеют соотношение сторон 2:3.

С появлением адаптивного дизайна поддержание пропорций стало все более важным для веб-разработчиков, особенно с учетом того, что размеры изображений различаются, а размеры элементов изменяются в зависимости от доступного пространства.

Вот несколько примеров ситуаций, когда сохранение пропорций становится важным:

  • Создание адаптивных iframe, ширина которых составляет 100% от ширины родительского элемента, а высота должна сохранять определенное соотношение сторон области просмотра.
  • Создание встроенных контейнеров-заполнителей для изображений, видео и встроенных элементов, чтобы предотвратить перекомпоновку при загрузке и занятии элементами пространства.
  • Создание единообразного, адаптивного пространства для интерактивной визуализации данных или SVG-анимации.
  • Создание единообразного, адаптивного пространства для многоэлементных компонентов, таких как карточки или даты календаря.
  • Создание единообразного, адаптивного пространства для множества изображений разных размеров (может использоваться совместно с object-fit ).

Объектно-соответствующий

Определение соотношения сторон помогает нам подбирать размеры медиафайлов в адаптивном контексте. Еще один инструмент в этой области — свойство object-fit , которое позволяет пользователям описывать, как объект (например, изображение) внутри блока должен заполнять этот блок:

Демонстрационная визуализация соответствия объекта
Демонстрация различных значений параметра object-fit . Смотрите демо на Codepen .

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

object-fit: cover обычно работает в большинстве ситуаций, обеспечивая удобный и единообразный интерфейс при работе с изображениями разных размеров, однако при этом теряется информация (изображение обрезается по самым длинным сторонам).

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

Старый трюк: сохранение пропорций с помощью padding-top

Использование свойства padding-top позволяет установить соотношение сторон 1:1 для изображений предварительного просмотра в карусели.
Использование padding-top позволяет установить соотношение сторон 1:1 для изображений предварительного просмотра в карусели.

Для повышения адаптивности можно использовать соотношение сторон. Это позволяет задать определенный размер соотношения и настроить остальные элементы медиаконтента по отдельным осям (высота или ширина).

В настоящее время широко распространенное кроссбраузерное решение для сохранения соотношения сторон изображения в зависимости от его ширины известно как "хак с отступом сверху". Это решение требует наличия родительского контейнера и дочернего контейнера, размещенного абсолютно. Затем необходимо рассчитать соотношение сторон в процентах и ​​установить его в качестве значения padding-top . Например:

  • Соотношение сторон 1:1 = 1 / 1 = 1 = padding-top: 100%
  • Соотношение сторон 4:3 = 3 / 4 = 0,75 = padding-top: 75%
  • Соотношение сторон 3:2 = 2 / 3 = 0,66666 = padding-top: 66.67%
  • Соотношение сторон 16:9 = 9 / 16 = 0,5625 = padding-top: 56.25%

Теперь, когда мы определили значение соотношения сторон, мы можем применить его к нашему родительскому контейнеру. Рассмотрим следующий пример:

<div class="container">
  <img class="media" src="..." alt="...">
</div>

Затем мы могли бы написать следующий CSS-код:

.container {
  position: relative;
  width: 100%;
  padding-top: 56.25%; /* 16:9 Aspect Ratio */
}

.media {
  position: absolute;
  top: 0;
}

Сохранение соотношения сторон с помощью aspect-ratio

Использование параметра aspect-ratio позволяет установить соотношение сторон 1:1 для изображений предварительного просмотра в карусели.
Использование aspect-ratio позволяет установить соотношение сторон 1:1 для изображений предварительного просмотра в карусели.

К сожалению, вычисление значений padding-top не очень интуитивно понятно и требует дополнительных затрат и позиционирования. С новым внутренним свойством CSS aspect-ratio язык для управления соотношением сторон стал гораздо понятнее.

Используя ту же разметку, мы можем заменить: padding-top: 56.25% на aspect-ratio: 16 / 9 , установив aspect-ratio в заданное соотношение width и height .

Используя подкладку сверху
.container {
  width: 100%;
  padding-top: 56.25%;
}
Использование соотношения сторон
.container {
  width: 100%;
  aspect-ratio: 16 / 9;
}

Использование aspect-ratio вместо padding-top гораздо понятнее и не меняет свойства padding, заставляя их делать что-то за пределами своей обычной области применения.

Это новое свойство также добавляет возможность устанавливать соотношение сторон в auto , где «заменяемые элементы с заданным соотношением сторон используют это соотношение сторон; в противном случае блок не имеет предпочтительного соотношения сторон». Если одновременно указаны и auto , и <ratio> , предпочтительным соотношением сторон будет заданное соотношение width к height за исключением случаев, когда заменяемый элемент имеет заданное соотношение сторон, в этом случае используется другое соотношение сторон.

Пример: согласованность в сетке

Это отлично работает и с механизмами компоновки CSS, такими как CSS Grid и Flexbox. Рассмотрим список с дочерними элементами, для которых необходимо сохранить соотношение сторон 1:1, например, сетку из иконок спонсоров:

<ul class="sponsor-grid">
  <li class="sponsor">
    <img src="..." alt="..."/>
  </li>
  <li class="sponsor">
    <img src="..." alt="..."/>
  </li>
</ul>
.sponsor-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
}

.sponsor img {
  aspect-ratio: 1 / 1;
  width: 100%;
  object-fit: contain;
}
Изображения расположены в сетке, при этом родительский элемент имеет различное соотношение сторон. Демонстрацию смотрите на Codepen.

Пример: предотвращение смещения макета.

Еще одна замечательная особенность aspect-ratio заключается в том, что оно может создавать пространство-заполнитель, предотвращая кумулятивное смещение макета и обеспечивая лучшие показатели веб-контента . В первом примере загрузка ресурса из API, такого как Unsplash, приводит к смещению макета после завершения загрузки медиафайла.

Видеоролик, демонстрирующий кумулятивное смещение макета, происходящее при отсутствии заданного соотношения сторон для загруженного объекта. Видео записано с использованием эмулированной сети 3G.

Использование aspect-ratio , с другой стороны, создает заполнитель, предотвращающий это изменение макета:

img {
  width: 100%;
  aspect-ratio: 8 / 6;
}
Видео с заданным соотношением сторон устанавливается на загруженный ресурс. Это видео записано с использованием эмулированной сети 3G. Смотрите демонстрацию на Codepen.

Дополнительный совет: атрибуты изображения для определения соотношения сторон.

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

В нашем примере, зная размеры изображения 800x600 пикселей, разметка изображения будет выглядеть так: <img src="image.jpg" alt="..." width="800" height="600"> . Если отправленное изображение имеет такое же соотношение сторон, но не обязательно точно такие же значения в пикселях, мы все равно можем использовать значения атрибутов изображения для установки соотношения сторон в сочетании со стилем width: 100% , чтобы изображение занимало нужное пространство. В целом это будет выглядеть так:

<!-- Markup -->
<img src="image.jpg" alt="..." width="8" height="6">
/* CSS */
img {
  width: 100%;
  height: auto;
}

В итоге эффект тот же, что и при задании aspect-ratio изображения с помощью CSS, и удается избежать кумулятивного смещения макета ( см. демонстрацию на Codepen ).

Заключение

Благодаря новому свойству CSS aspect-ratio , запуск приложения в различных современных браузерах и поддержание правильных соотношений сторон в медиаконтейнерах и макетах становится немного проще.

Фотографии Эми Шамблен и Лайонела Густава предоставлены Unsplash.