1K подписчиков

Соотношение сторон это круто

Источник: WebForMyself.

Источник: WebForMyself.com

Мне одному кажется, что большую часть времени изучение новых возможностей CSS приводит к изучению не только принципа работы одного конкретного свойства, а набора свойств и того, как они работают вместе? А порой и изучения всей спецификации. Нет, я не жалуюсь: понятное дело, что свойства нужно рассматривать как часть экосистемы. Но признаюсь, я обожаю, когда новое CSS свойство появляется в браузерах, и его изучение не требует много сил, и все просто работает.

Свойство aspect-ratio отвечает всем этим требованиям и решает все глупые костыли (соотношение сторон) одной строкой. Свойство поддерживается уже год, но уверенно его использовать мы смогли только после релиза для Safari в сентябре 2021.

Padding хак, прощай

Раньше для соблюдения элементами соотношения сторон нам нужно было писать довольно страшный CSS:

Этот способ назывался паддинг хак потому что, ну, он именно это и делает. Кастомное свойство отрезает повторение на случай, если нужно более одного соотношения сторон. Никто в здравом уме не хочет писать так. С помощью Ratio Buddy можно сгенерировать Sass сниппет.

Практическое использование aspect-ratio

Работа с aspect-ratio гораздо проще: указываете ширину и высоту соотношения сторон через слэш или укажите число с плавающей точкой. 2 примера соотношения сторон ниже работают одинаково:

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

Демонстрация

Увеличение размеров элемента и подстройка под содержимое

aspect-ratio умеет изменять размер относительно дочерних элементов и родительских. Это значит, что он подстраивается как под контент, так и под контекст. Все 3 блока ниже имеют соотношение сторон 2 / 1 и явно заданную ширину. Текст в третьем блоке не помещается, из-за чего блок вертикально расширяется, подстраиваясь под контент.

Источник: WebForMyself.-2

Демонстрация

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

Источник: WebForMyself.-3

Демонстрация

Соотношение сторон изображений и object-fit

Сила aspect-ratio раскрывается при работе изменении размеров изображений в сочетании с object-fit. С помощью object-fit: cover можно создать превью как для галереи изображений:

Демонстрация

Или можно использовать object-fit: contain для сетки логотипов.

Демонстрация

Нужно добавить, что object-fit обязательно требует явно заданной ширины и высоты элемента, чтобы «подогнать» размеры. Разберем разметку ниже (изображение внутри блока с соотношением сторон):

Чтобы изображение целиком заполнило родительский блок, необходимо написать следующие стили:

Довольно часто требуется поместить что-то в блок с соотношением сторон, как выше. Однако блок-обертку можно было опустить и добавить свойство aspect-ratio прямо на изображение вместо height или width:

Блоки с соотношением сторон в контексте

В демо выше для галереи используется Grid или Flexbox. Все работает, как и ожидается. А что есть у нас сетка, внутри которой блоки с соотношением сторон? А в блоках только текст, или они вообще пустые. Нам стоит обратить внимание на то, что FlexBox и Grid по умолчанию задают align-items: stretch. То есть если у нас в сетки есть одна ячейка с контентом, которые не помещается в соотношение сторон, то другие ячейки начнут увеличивать высоту, равняясь на самый длинный элемент и игнорируя соотношение сторон (предполагается, что для ячеек явно задана ширина, а не высота, так как это более частый сценарий):

Источник: WebForMyself.-4

Для нашего дизайна поведение ожидаемое и часто подходящее по умолчанию. Но если мы все же хотим соблюдать соотношение сторон ячеек, даже если один элемент в ряду выше остальных, то нам необходимо указать другое значение для align-items, отличное от значения по умолчанию для Grid и Flexbox контейнера:

Источник: WebForMyself.-5

Демонстрация

Минимальное соотношение сторон

Есть место, где стандартное поведение полезно. Когда в нашем UI компоненте есть текст с одной стороны и изображений с другой. Например, CTA элемент (элемент призывающий к действию). Если к изображению добавить соотношение сторон, то колонка с текстом будет такой же высоты, что и высота изображения. А если текст не будет помещаться в свой блок, то уже изображение будет увеличиваться для соблюдения высоты блока с текстом.

Источник: WebForMyself.-6

Демонстрация

В этом примере aspect-ratio ведет себя не как фиксированное значение, а как «минимальное».

Поддержка в браузерах

Сейчас поддержка хорошая. В большинстве случаев не придется городить фолбэки. Пользователи все так же увидят ваш контент. Просто он не будет идеально соблюдать желаемое соотношение сторон. Однако в случае с галереей изображений на object-fit любое большое изображение приведет к тому, что все превьюшки в ряду увеличатся, из-за чего изображения могут неудачно обрезаться.

Источник: WebForMyself.-7

Проблему можно пофиксить, если на grid контейнер добавить align-items: start.

Источник: WebForMyself.-8

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

Заключение

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

Читайте нас в Telegram, VK

Источник: css-irl.info

#css #css3 #разработка сайтов