Как использовать CSS aspect-ratio

Источник: «How to Use CSS aspect-ratio»
Бывают случаи, когда действительно необходимо поддерживать определённое соотношение между шириной и высотой отзывчивых элементов на веб-странице. Долгое время это можно было сделать с помощью различных CSS-трюков. Свойство CSS aspect-ratio изменило ситуацию: теперь мы можем задавать соотношение сторон элемента в одной строке кода. Давайте рассмотрим, как использовать свойство aspect-ratio.

Примеры, когда соотношение сторон имеет значение

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

Однако иногда возникают причины для введения ограничений на размер элементов. Например, мы можем захотеть сохранить соотношение ширины и высоты некоторых элементов — таких, как отзывчивые видеоролики YouTube, элементы галереи изображений или закруглённые аватары.

Давайте сначала рассмотрим три практических варианта использования CSS свойства aspect-ratio, а затем расскажем о том, как оно работает.

Отзывчивые видеоролики YouTube

Если вы когда-либо вставляли видео с YouTube на веб-страницу, то знаете, что код для вставки представляется в виде <iframe> с фиксированной шириной и высотой. Это нормально, но могло бы быть и лучше. Скорее всего, его ширина не будет равна ширине вашего контейнера, что не очень приятно. Но ещё хуже то, что часть кода может быть потеряна за пределами экрана на маленьких экранах просмотра.

Как выглядит вставка YouTube с фиксированной шириной на настольном (слева) и мобильном (справа) компьютерах.
Как выглядит вставка YouTube с фиксированной шириной на настольном (слева) и мобильном (справа) компьютерах.

На самом деле мы хотим, чтобы встроенное видео заполняло определённое пространство в нашем дизайне и реагировало на различную ширину области просмотра. Для простоты предположим, что оно должно заполнять 100% ширины своего контейнера.

Рассмотрим два способа достижения этой цели — сначала старый, с помощью CSS-трюков, а затем новый, с помощью aspect-ratio.

Делаем видео на YouTube отзывчивым с помощью padding хака

YouTube предоставляет нам следующий код для встраивания (упрощённый для экономии места):

<iframe width="560" height="315" src=""></iframe>

Традиционным приёмом, позволяющим сделать наши вставки отзывчивыми, является padding хаком. Первое, что мы должны сделать, это разделить ширину iframe на высоту, что даст нам отношение ширины к высоте. Видеоролики YouTube обычно имеют размер 560 на 315 пикселей, поэтому нам нужно разделить 315 на 560, что даст нам .5625. Это означает, что высота нашего iframe YouTube составляет 56,25% от его ширины. Это соотношение составляет 16:9, поэтому не забывайте об этом.

Теперь мы можем настроить нашу отзывчивую вставку YouTube в несколько шагов. Во-первых, мы обернём элемент вокруг iframe, например div:

<div>
<iframe></iframe>
</div>

Затем мы устанавливаем для div значение position: relative и задаём ему нижний padding 56,25%. Браузер вычислит это процентное значение на основе ширины div:

div {
position: relative;
padding-bottom: 56.25%;
}

На рисунке ниже показан div c отступом, выделенный зелёным цветом с помощью средств разработчика браузера.

Padding хак

Примечание: если вы не хотите возиться с вычислением процентного соотношения подкладок, вы можете позволить браузеру сделать это за вас. Просто вставьте ширину и высоту iframe следующим образом: padding-bottom: calc(315 / 560 * 100%).

Далее мы устанавливаем для iframe значение position: absolute и задаём его ширину и высоту равными 100%:

iframe {
position: absolute;
width: 100%;
height: 100%;
}

Теперь наша вставка YouTube будет отзывчивой, заполняя 100% ширины контейнера независимо от размера экрана, сохраняя при этом соотношение сторон, как показано ниже.

See the Pen

Примечание: существует множество других способов реализации padding хака, например, использование ::before или ::after вместо дополнительного div. Их легко найти в Интернете по запросу padding hack.

Делаем видео на YouTube отзывчивым с помощью aspect-ratio

С помощью CSS свойства aspect-ratio мы можем сделать видео на YouTube отзывчивым, используя гораздо меньше кода. Больше не нужна обёртка из div. Можно просто установить следующие стили для iframe:

iframe {
width: 100%;
aspect-ratio: 16/9;
}

Классно. Проверьте это на CodePen.

See the Pen

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

iframe {
--ratio: calc(315 / 560);
width: 100%;
aspect-ratio: 1/var(--ratio);
}

Мы знаем исходные ширину и высоту нашего iframe, поэтому вставляем их в пользовательское свойство (--ratio), разделив высоту на ширину с помощью функции calc(). Затем используем пользовательское свойство в CSS-переменной как часть aspect-ratio. Теперь наше значение соотношения сторон, по сути, равно 1/0,5625. Таким образом, мы можем использовать числа с плавающей точкой в значениях aspect-ratio. (Конечно, если вы хотите применить это соотношение к другим элементам, то объявите пользовательское свойство для родительского элемента, расположенного выше по дереву, или для самого элемента :root).

Ещё одна вариация на эту тему — просто использовать calc() без пользовательского свойства:

iframe {
width: 100%;
aspect-ratio: 1/calc(315 / 560);
}

Это хорошо, если мы используем это значение соотношения сторон только для iframe.

Повеселитесь и попробуйте эти варианты в приведённой выше демонстрации CodePen.

Отзывчивая галерея изображений

Допустим, мы хотим отобразить галерею изображений в виде серии гибких квадратных боксов. Чтобы сохранить квадратность боксов, можно воспользоваться padding хаком, но вместо этого можно использовать aspect-ratio. (Изображения взяты из моего недавнего туристического похода с помощью сайта Unsplash).

Вот наш HTML:

<ul>
<li><img src="1.jpg" alt=""></li>
<li><img src="2.jpg" alt=""></li>

<li><img src="11.jpg" alt=""></li>
<li><img src="12.jpg" alt=""></li>
</ul>

Вот ключевой CSS:

ul {
display: grid;
}

li {
aspect-ratio: 1/1;
}

img {
object-fit: cover;
}

Приведённая ниже демонстрация CodePen показывает этот код в действии.

See the Pen

Это очень простой демонстрационный пример. Столбцы сетки имеют ширину 1fr, а aspect-ratio: 1/1 гарантирует, что ячейки останутся идеально квадратными, независимо от ширины или ширины браузера. Это очень удобный способ управления высотой строк сетки.

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

Попробуйте поиграть со свойством aspect-ratio в демонстрационном примере выше. Что произойдёт, если изменить значение с 1/1 на 2/1 и т.д.?

Поддержание постоянных размеров аватаров с помощью aspect-ratio

В своей недавно вышедшей книге Unleashing the Power of CSS Стефани Эклз демонстрирует использование свойства aspect-ratio для обеспечения согласованных размеров аватара. С помощью свойства aspect-ratio в сочетании со свойством object-fit мы можем обеспечить постоянный размер аватара независимо от соотношения исходного изображения и без его искажения.

Вот ключевой CSS:

img {
aspect-ratio: 1; /* то же, что и aspect-ratio: 1/1 - см. ниже */
object-fit: cover;
border-radius: 50%;
width: 100%;
height: 100%;
}

На следующем примере CodePen это показано в действии.

See the Pen

В качестве эксперимента попробуйте закомментировать строку aspect-ratio: 1; в приведённом выше CodePen и посмотреть, что получится без неё! (Её можно отключить, просто добавив символ / спереди: /aspect-ratio: 1;).

Полезные сведения об aspect-ratio

Каждый элемент имеет соотношение сторон. Если мы не задаём соотношение сторон элемента, то по умолчанию его соотношение сторон принимает значение auto. Если этот элемент является заменяемым элементом, например, изображением, то его соотношение сторон определяется его естественной шириной и высотой. (Это соотношение сохранится, даже если мы зададим другую ширину или высоту с помощью CSS).

Соотношение сторон сравнивает ширину (x) с высотой (y), при этом между двумя значениями ставится знак /: x/y. По обе стороны от косой черты могут стоять пробелы: x / y. Если указано только одно значение, то оно представляет собой x, а значение y считается равным 1. Таким образом, aspect-ratio: 1 равно aspect-ratio: 1/1, а aspect-ratio: 2 равно aspect-ratio: 2/1.

Значение aspect-ratio может включать слово auto — например, aspect-ratio: auto 1/2. Значение auto будет применяться к заменяемым элементам, таким как изображения и видео. (Другими словами, элемент сохранит своё естественное соотношение сторон). Соотношение 1/2 будет применяться к незамещённым элементам, таким как div.

Значения могут включать числа с плавающей точкой, например 0,5, как мы видели выше. Таким образом, aspect-ratio: 1.5/1 является допустимым и эквивалентно aspect-ratio: 3/2.

Мы также можем использовать var() и calc() как часть значений aspect-ratio, как показано выше.

Для незамещённых элементов, таких как div, не нужно задавать ширину, чтобы соотношение сторон вступило в силу. Если заданы ширина или высота, то соотношение сторон будет основано на них. Если для элемента заданы и ширина, и высота, то любое значение aspect-ratio будет проигнорировано. Также можно столкнуться с неожиданными результатами при применении комбинаций ширины, высоты, max-width и min-width к контейнерам вместе с aspect-ratio, как обсуждается в этой ветке форума SitePoint.

Задавать высоту для элементов контейнера всегда опасно, так как это может привести к высыпанию содержимого за пределы контейнера. Интересно, что если применить соотношение сторон к контейнеру и содержимое не поместится, то контейнер расширится. Таким образом, как сказано в спецификации, aspect-ratio устанавливает предпочтительное ограничение, а не фиксированное. Это можно отменить, установив для контейнера значение overflow: auto.

Заключение

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

Более подробную информацию о css свойстве aspect-ratio можно найти в справочнике MDN, а также в спецификации W3C.

Если вы хотите узнать больше об интересных возможностях CSS, рекомендую вам ознакомиться с книгой Unleashing the Power of CSS, в которой Стефани Эклз рассказывает обо всех удивительных инновациях, позволяющих сэкономить время, появившиеся в CSS в последнее время.

Дополнительные материалы

Предыдущая Статья

Автоматическая генерация RSS лент в приложении Laravel

Следующая Статья

Как использовать защиту типов в TypeScript