Что может сломать aspect-ratio в CSS
Здесь нужен квадрат
или Нужно, чтобы размер соответствовал 16:9 в
— вполне разумные требования к дизайну. Особенно в адаптивной среде, где нужно стараться не думать о точных размерах, потому что знаете, что они могут измениться.<video>
Обычно это работает
Есть <div>
, размещённый в контейнере. <div>
естественным образом занимает всю ширину. Соотношение сторон установлено: 1/1
; таким образом, это квадрат.
Пример с видео из введения также целесообразен. В этом случае по историческим причинам, <video>
по умолчанию имеет ширину 300px
. Поэтому, если нужно, чтобы он заполнил всё пространство, необходимо задать ширину: 100%
, и тогда aspect-ratio
сделает то, что требуется:
Элемент в Grid будет вести себя также хорошо. Вот здесь 12 <div>
помещены в Grid с квадратным соотношением сторон, и они прекрасно его соблюдают:
Но всё может пойти не так, и в результате получится элемент, не соблюдающий aspect-ratio
.
Потенциальная проблема №1. Установка обоих размеров
Если для элемента заданы и высота, и ширина, то aspect-ratio
игнорируется. Это относится и к размеру блока и размеру строки, конечно, логические свойства эквивалентны.
.el {
inline-size: 300px;
block-size: 200px;
aspect-ratio: 1 / 1; /* ничего не делает */
}
Это логично (какое из значений должно быть проигнорировано?), но это может запутать, если одно из измерений задано не там, где вы ожидали. Может быть, предполагалось задать height
и aspect-ratio
для <img>
, не учитывая, что в базовом CSS-файле для изображений устанавливается width
, и тогда aspect-ratio
не сработает.
Это справедливо и для значений вне CSS. Например, атрибут height
заданный в теге <img>
(который настоятельно рекомендуется использовать) считается другой осью и не позволяет работать aspect-ratio
:
Обратите внимание, что ограничение размеров с помощью min-width
, min-height
, min-inline-size
, min-block-size
, max-width
, max-height
, max-block-size
, max-inline-size
будет соблюдено, но также может нарушить работу aspect-ratio
.
Потенциальная проблема №2. Растягивание
Есть три <div>
в контейнере flex с разным соотношением сторон. Но… у них одинаковые размеры:
Почему?! У этих <div>
задан только width
, без height
(или его логического эквивалента). Проблема в том, что высота/размер блока задаются принудительно, потому что на flex элементы влияет стандартное align-items: stretch;
.
Если изменить дефолтное значение на align-items: flex-start;
в родительском flex контейнере, то можно увидеть, как aspect-ratio
заработает:
Подобное может быть справедливо для любого из значений stretch
в CSS grid или flexbox. Например, в CSS grid есть justify-items: stretch;
, способный вызвать подобную проблему.
Потенциальная проблема №3. Контент, увеличивающий высоту
Одним из способов, используемых нами для изменения aspect-ratio
, был старый трюк Uncle Dave's Padded Box Trick. Для создания блока используется padding-bottom
на блоке с нулевой высотой. Процентный padding
— это процент от width
, так что таким образом устанавливается связь между шириной и высотой. Но затем внутрь этого блока помещается абсолютно позиционированный блок. Проблема с абсолютным позиционированием заключается в том, что содержимое оказывается вне нормального потока документа. Так что если, например, разместить внутри текст, который будет выше блока, возникнут проблемы. Ниже показано, как содержимое выходит за пределы блока. Блок имеет правильное соотношение сторон, но вряд ли это желаемый результат:
Если вместо этого использовать aspect-ratio
для нашего блока, мы получим:
Теперь оранжевый блок содержит весь контент, что, опять же, вероятно, является желаемым результатом в большинстве ситуаций. Но, что примечательно, блок больше не имеет того aspect-ratio
, который мы объявили.
Я пропустил какой-нибудь способ, с помощью которого aspect-ratio
может сломаться или привести к неожиданным результатам? Я полагаю, что поддержка браузерами — это ещё одна вещь, которую следует учитывать, но она довольно надёжна.