Как использовать CSS aspect-ratio
aspect-ratio
изменило ситуацию: теперь мы можем задавать соотношение сторон элемента в одной строке кода. Давайте рассмотрим, как использовать свойство aspect-ratio
.Примеры, когда соотношение сторон имеет значение
По своей природе Web — это подвижная среда, и обычно лучше позволить элементам на веб-странице быть как можно более подвижными и гибкими.
Однако иногда возникают причины для введения ограничений на размер элементов. Например, мы можем захотеть сохранить соотношение ширины и высоты некоторых элементов — таких, как отзывчивые видеоролики YouTube, элементы галереи изображений или закруглённые аватары.
Давайте сначала рассмотрим три практических варианта использования CSS свойства aspect-ratio
, а затем расскажем о том, как оно работает.
Отзывчивые видеоролики YouTube
Если вы когда-либо вставляли видео с YouTube на веб-страницу, то знаете, что код для вставки представляется в виде <iframe>
с фиксированной шириной и высотой. Это нормально, но могло бы быть и лучше. Скорее всего, его ширина не будет равна ширине вашего контейнера, что не очень приятно. Но ещё хуже то, что часть кода может быть потеряна за пределами экрана на маленьких экранах просмотра.
На самом деле мы хотим, чтобы встроенное видео заполняло определённое пространство в нашем дизайне и реагировало на различную ширину области просмотра. Для простоты предположим, что оно должно заполнять 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 отступом, выделенный зелёным цветом с помощью средств разработчика браузера.
Примечание: если вы не хотите возиться с вычислением процентного соотношения подкладок, вы можете позволить браузеру сделать это за вас. Просто вставьте ширину и высоту iframe
следующим образом: padding-bottom: calc(315 / 560 * 100%)
.
Далее мы устанавливаем для iframe
значение position: absolute
и задаём его ширину и высоту равными 100%
:
iframe {
position: absolute;
width: 100%;
height: 100%;
}
Теперь наша вставка YouTube будет отзывчивой, заполняя 100% ширины контейнера независимо от размера экрана, сохраняя при этом соотношение сторон, как показано ниже.
Примечание: существует множество других способов реализации padding хака, например, использование ::before
или ::after
вместо дополнительного div
. Их легко найти в Интернете по запросу padding hack
.
Делаем видео на YouTube отзывчивым с помощью aspect-ratio
С помощью CSS свойства aspect-ratio
мы можем сделать видео на YouTube отзывчивым, используя гораздо меньше кода. Больше не нужна обёртка из div
. Можно просто установить следующие стили для iframe
:
iframe {
width: 100%;
aspect-ratio: 16/9;
}
Классно. Проверьте это на CodePen.
Если вы не знаете соотношения сторон элемента и не хотите доставать калькулятор, можно предоставить браузеру возможность самому определить это соотношение, используя ширину и высоту элемента. Вот вариант приведённого выше 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 показывает этот код в действии.
Это очень простой демонстрационный пример. Столбцы сетки имеют ширину 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 это показано в действии.
В качестве эксперимента попробуйте закомментировать строку 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 в последнее время.