Как работает CSS Aspect Ratio
Вы установили width: 100% на контейнер изображения, но высота схлопывается до нуля до загрузки изображения — вызывая тот самый раздражающий сдвиг макета, который ненавидят пользователи. CSS-свойство aspect-ratio решает эту проблему напрямую, позволяя зарезервировать место для контента до его появления.
Эта статья объясняет, как свойство aspect-ratio участвует в расчётах размеров CSS, чем оно отличается для замещаемых и незамещаемых элементов, и почему оно заменяет старую технику padding-hack для адаптивных макетов.
Ключевые моменты
- Свойство
aspect-ratioопределяет предпочтительное соотношение ширины к высоте, которое применяется только когда хотя бы одно измерение установлено как auto. - Оно формирует размеры блока элемента, а не медиа внутри него — комбинируйте его с
object-fitдля управления тем, как изображения или видео заполняют пространство. - Оно полностью заменяет устаревший padding-bottom hack, устраняя необходимость в элементах-обёртках, абсолютном позиционировании и непонятных вычислениях.
- В контексте flexbox и grid следите за взаимодействиями с автоматическим определением размеров, которые могут переопределить или конфликтовать с вычисленными размерами aspect-ratio.
Понимание CSS-свойства Aspect-Ratio
Свойство aspect-ratio определяет предпочтительное соотношение ширины к высоте для блока элемента. Ключевое слово — «предпочтительное» — оно действует только когда хотя бы одно измерение является автоматическим.
.video-container {
width: 100%;
aspect-ratio: 16 / 9;
}
Здесь ширина явная (100% от родителя), поэтому браузер вычисляет высоту автоматически, используя соотношение 16:9. Если вы установите и width, и height явно, aspect-ratio обычно не влияет на используемый размер, поскольку определённые размеры имеют приоритет в обычных расчётах макета.
Синтаксис и значения
Свойство принимает три формы:
aspect-ratio: 16 / 9; /* соотношение ширина / высота */
aspect-ratio: 1; /* то же, что 1 / 1 (квадрат) */
aspect-ratio: auto 3 / 2; /* auto с резервным соотношением */
Ключевое слово auto указывает браузеру использовать естественное соотношение сторон элемента, если оно существует. Комбинация auto 3 / 2 означает: использовать естественное соотношение для замещаемых элементов, в противном случае использовать 3/2.
Замещаемые и незамещаемые элементы
Свойство ведёт себя по-разному в зависимости от типа элемента.
Замещаемые элементы (<img>, <video>, <iframe>) имеют внутренние размеры. По умолчанию aspect-ratio: auto использует их естественное соотношение. Когда вы указываете aspect-ratio: auto 16/9, браузер использует естественное соотношение медиа после загрузки, но заранее резервирует место, используя 16/9 — предотвращая сдвиг макета.
Незамещаемые элементы (<div>, <section>) не имеют внутреннего соотношения. Установка aspect-ratio: 1 на <div> с width: 200px создаёт квадрат 200×200. Свойство напрямую контролирует размеры блока.
Aspect-Ratio формирует блок, а не медиа
Критическое различие: aspect-ratio контролирует размеры контейнера, а не то, как медиа заполняет его. Для изображений или видео используйте object-fit для управления поведением медиа внутри блока:
.thumbnail {
aspect-ratio: 1;
object-fit: cover;
}
Это создаёт квадратный контейнер, где изображение покрывает область, обрезаясь при необходимости.
CSS Aspect Ratio против Padding Hack
До того, как aspect-ratio получило поддержку браузеров, разработчики использовали трюк с процентным padding-bottom:
/* Устаревший padding hack */
.video-wrapper {
position: relative;
padding-bottom: 56.25%; /* 9/16 = 0.5625 */
height: 0;
}
.video-wrapper iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
Это работает, потому что процентные значения padding вычисляются относительно ширины родителя, создавая высоту на основе соотношения. Но это требует элементов-обёрток, абсолютного позиционирования и непонятной математики.
Современный подход чище:
.video-wrapper {
aspect-ratio: 16 / 9;
}
.video-wrapper iframe {
width: 100%;
height: 100%;
}
Используйте aspect-ratio по умолчанию. Оставляйте padding hack только если вам необходимо поддерживать устаревшие браузеры, такие как IE.
Discover how at OpenReplay.com.
Aspect-Ratio во Flexbox и Grid
Использование aspect-ratio в flexbox и grid макетах работает, но взаимодействия с автоматическим определением размеров могут давать неожиданные результаты.
В CSS Grid aspect-ratio работает естественно с треками автоматического размера:
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}
.grid-item {
aspect-ratio: 1;
}
Каждый элемент становится квадратным, с высотой, соответствующей его ширине, определённой grid.
Во Flexbox имейте в виду, что flex-grow и flex-shrink влияют на вычисленную ширину, которая затем определяет высоту через aspect-ratio. Если элементы растягиваются неожиданно, проверьте ваши flex-свойства. Установка явного width или flex-basis на элементе даёт aspect-ratio стабильное измерение для работы.
Для обеих систем макетов установите min-height: 0 на элементах, если контент выходит за пределы высоты, ограниченной aspect-ratio.
Практические адаптивные макеты с Aspect-Ratio
Вот распространённый паттерн для адаптивных изображений карточек:
.card-image {
width: 100%;
aspect-ratio: 4 / 3;
object-fit: cover;
}
И для встроенных видео:
.embed-container {
width: 100%;
max-width: 800px;
aspect-ratio: 16 / 9;
}
Оба паттерна резервируют место в макете немедленно, устраняя кумулятивный сдвиг макета (CLS).
Заключение
Свойство aspect-ratio определяет предпочтительное соотношение, используемое когда хотя бы одно измерение является auto. Оно формирует блок элемента — а не медиа-контент — и заменяет технику padding-hack для современных браузеров. При работе с изображениями или видео комбинируйте его с object-fit для управления тем, как медиа заполняет пространство. В контексте flexbox и grid следите за взаимодействиями с автоматическим определением размеров, которые могут влиять на вычисленные размеры.
Часто задаваемые вопросы
Нет. Свойство aspect-ratio действует только когда хотя бы одно измерение является auto. Если вы установите и ширину, и высоту явными значениями, эти размеры имеют приоритет, и объявление aspect-ratio полностью игнорируется.
Установите aspect-ratio с резервным соотношением, например aspect-ratio: auto 4 / 3, чтобы браузер мог зарезервировать место до загрузки изображения. Для лучших результатов и минимального сдвига макета также включите явные атрибуты width и height на элементе img, чтобы браузер сразу знал его внутренние размеры.
Для всех современных браузеров — да. Свойство aspect-ratio поддерживается в Chrome, Firefox, Safari и Edge. Единственная причина сохранять padding-bottom hack — если вам нужно поддерживать Internet Explorer, который вообще не поддерживает aspect-ratio.
Flex-элементы имеют значение min-height: auto по умолчанию, что может предотвратить сжатие элемента ниже высоты его контента. Установите min-height: 0 на flex-элементе, чтобы высота, ограниченная aspect-ratio, соблюдалась. Также проверьте, что flex-grow или flex-shrink не переопределяют ширину, от которой зависит aspect-ratio.
Complete picture for complete understanding
Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.
Check our GitHub repo and join the thousands of developers in our community.