Соотношение сторон это круто
Свойство aspect-ratio отвечает всем этим требованиям и решает все глупые костыли (соотношение сторон) одной строкой. Свойство поддерживается уже год, но уверенно его использовать мы смогли только после релиза для Safari в сентябре 2021.
Padding хак, прощай
Содержание статьи:
Раньше для соблюдения элементами соотношения сторон нам нужно было писать довольно страшный CSS:
CSS .aspect-box { position: relative; } .aspect-box::before { display: block; content: ”; width: 100%; padding-bottom: calc(100% / (var(–aspect-ratio, 3 / 2))); } .aspect-box > :first-child { position: absolute; top: 0; right: 0; bottom: 0; left: 0; }
123456789101112131415161718 | .aspect-box { position: relative;} .aspect-box::before { display: block; content: ”; width: 100%; padding-bottom: calc(100% / (var(–aspect-ratio, 3 / 2)));} .aspect-box > :first-child { position: absolute; top: 0; right: 0; bottom: 0; left: 0;} |
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
Этот способ назывался паддинг хак потому что, ну, он именно это и делает. Кастомное свойство отрезает повторение на случай, если нужно более одного соотношения сторон. Никто в здравом уме не хочет писать так. С помощью Ratio Buddy можно сгенерировать Sass сниппет.
Практическое использование aspect-ratio
Работа с aspect-ratio гораздо проще: указываете ширину и высоту соотношения сторон через слэш или укажите число с плавающей точкой. 2 примера соотношения сторон ниже работают одинаково:
CSS .aspect-box { aspect-ratio: 3 / 2; } .aspect-box { aspect-ratio: 1.5; }
1234567 | .aspect-box { aspect-ratio: 3 / 2;} .aspect-box { aspect-ratio: 1.5;} |
Ширину и высоту можно явно указать для элемента, и aspect-ratio будет работать ровно так, как вы ожидаете: если какое-то разрешение не указано, оно автоматически определится по соотношению сторон. Если указать для ширины и высоты не auto, то соотношение сторон больше не применяется. Это не баг. Так и задумано, это удобно.
Демонстрация
Увеличение размеров элемента и подстройка под содержимое
aspect-ratio умеет изменять размер относительно дочерних элементов и родительских. Это значит, что он подстраивается как под контент, так и под контекст. Все 3 блока ниже имеют соотношение сторон 2 / 1 и явно заданную ширину. Текст в третьем блоке не помещается, из-за чего блок вертикально расширяется, подстраиваясь под контент.
Демонстрация
Если вместо ширины явно указать высоту, то элемент не будет расширяться. Вместо этого текст выйдет за пределы элемента (можно поправить с помощью свойства overflow).
Демонстрация
Соотношение сторон изображений и object-fit
Сила aspect-ratio раскрывается при работе изменении размеров изображений в сочетании с object-fit. С помощью object-fit: cover можно создать превью как для галереи изображений:
Демонстрация
Или можно использовать object-fit: contain для сетки логотипов.
Демонстрация
Нужно добавить, что object-fit обязательно требует явно заданной ширины и высоты элемента, чтобы «подогнать» размеры. Разберем разметку ниже (изображение внутри блока с соотношением сторон):
<div class=”aspect-box”> <img src=”https://images.unsplash.com/photo…” alt=”Robin on a log” /> </div>
123 | <div class=”aspect-box”> <img src=”https://images.unsplash.com/photo…” alt=”Robin on a log” /></div> |
Чтобы изображение целиком заполнило родительский блок, необходимо написать следующие стили:
Практический курс по верстке адаптивного сайта с нуля!
Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3
CSS img { display: block; width: 100%; height: 100%; object-fit: cover; }
123456 | img { display: block; width: 100%; height: 100%; object-fit: cover;} |
Довольно часто требуется поместить что-то в блок с соотношением сторон, как выше. Однако блок-обертку можно было опустить и добавить свойство aspect-ratio прямо на изображение вместо height или width:
CSS img { display: block; width: 100%; aspect-ratio: 3 / 2; object-fit: cover; }
123456 | img { display: block; width: 100%; aspect-ratio: 3 / 2; object-fit: cover;} |
Блоки с соотношением сторон в контексте
В демо выше для галереи используется Grid или Flexbox. Все работает, как и ожидается. А что есть у нас сетка, внутри которой блоки с соотношением сторон? А в блоках только текст, или они вообще пустые. Нам стоит обратить внимание на то, что FlexBox и Grid по умолчанию задают align-items: stretch. То есть если у нас в сетки есть одна ячейка с контентом, которые не помещается в соотношение сторон, то другие ячейки начнут увеличивать высоту, равняясь на самый длинный элемент и игнорируя соотношение сторон (предполагается, что для ячеек явно задана ширина, а не высота, так как это более частый сценарий):
Для нашего дизайна поведение ожидаемое и часто подходящее по умолчанию. Но если мы все же хотим соблюдать соотношение сторон ячеек, даже если один элемент в ряду выше остальных, то нам необходимо указать другое значение для align-items, отличное от значения по умолчанию для Grid и Flexbox контейнера:
Демонстрация
Минимальное соотношение сторон
Есть место, где стандартное поведение полезно. Когда в нашем UI компоненте есть текст с одной стороны и изображений с другой. Например, CTA элемент (элемент призывающий к действию). Если к изображению добавить соотношение сторон, то колонка с текстом будет такой же высоты, что и высота изображения. А если текст не будет помещаться в свой блок, то уже изображение будет увеличиваться для соблюдения высоты блока с текстом.
Демонстрация
В этом примере aspect-ratio ведет себя не как фиксированное значение, а как «минимальное».
Поддержка в браузерах
Сейчас поддержка хорошая. В большинстве случаев не придется городить фолбэки. Пользователи все так же увидят ваш контент. Просто он не будет идеально соблюдать желаемое соотношение сторон. Однако в случае с галереей изображений на object-fit любое большое изображение приведет к тому, что все превьюшки в ряду увеличатся, из-за чего изображения могут неудачно обрезаться.
Проблему можно пофиксить, если на grid контейнер добавить align-items: start.
Если вам нужно предоставить запасной вариант для старых браузеров, то достаточно старого доброго функционального запроса:
CSS .aspect-box { /* Styles for browsers that don’t support aspect-ratio */ } @supports (aspect-ratio: 1 / 1) { .aspect-box { /* Styles for browsers that support aspect-ratio */ } }
123456789 | .aspect-box { /* Styles for browsers that don’t support aspect-ratio */} @supports (aspect-ratio: 1 / 1) { .aspect-box { /* Styles for browsers that support aspect-ratio */ }} |
Заключение
aspect-ratio – яркий пример скромного свойства, которое решает старые проблемы с CSS. Его просто использовать, и оно ведет себя соответственно контента. Никакой лишний CSS не нужен.
Автор: Michelle Barker
Источник: webformyself.com