44. Container Queries (@container)
CSS Container Queries
Заголовок раздела «CSS Container Queries»
Container Queries позволяют стилизовать элементы исходя из размера их контейнера, а не из размера всего окна браузера. Это делает компоненты по-настоящему переиспользуемыми: один и тот же компонент автоматически адаптируется к любому месту на странице.
Медиа-запросы vs Container Queries
Заголовок раздела «Медиа-запросы vs Container Queries»С медиа-запросами карточка реагирует на ширину экрана. Но что если она стоит в узком сайдбаре при широком экране? Медиа-запрос ничего не знает об этом.
Container Queries решают проблему: карточка реагирует на ширину своего контейнера.
/* Медиа-запрос — реагирует на экран */@media (min-width: 700px) { .card { font-size: 2em; }}
/* Container query — реагирует на контейнер */@container (width > 700px) { .card { font-size: 2em; }}Шаг 1 — объявить контейнер
Заголовок раздела «Шаг 1 — объявить контейнер»Сначала нужно сказать браузеру, что элемент является контейнером. Для этого используется свойство container-type:
.wrapper { container-type: inline-size; /* следим за шириной */}| Значение | Что делает |
|---|---|
inline-size | Следит за шириной (горизонтальная ось). Самый частый случай. |
size | Следит за шириной и высотой одновременно. |
normal | Контейнер для style queries, но не для size queries. |
Шаг 2 — написать @container
Заголовок раздела «Шаг 2 — написать @container»/* Стили по умолчанию */.card { display: block;}
/* Когда контейнер шире 500px */@container (width > 500px) { .card { display: flex; gap: 1rem; }}Синтаксис условий такой же, как в @media:
@container (min-width: 400px) { … } /* классика */@container (width > 400px) { … } /* современный Range Syntax */@container (400px < width < 800px) { … } /* диапазон */Именованные контейнеры
Заголовок раздела «Именованные контейнеры»Когда контейнеров несколько, нужно уточнить — к какому обращаемся. Имя задаётся через container-name:
.sidebar { container-type: inline-size; container-name: sidebar;}
.main-content { container-type: inline-size; container-name: main;}/* Реагирует только на контейнер с именем sidebar */@container sidebar (width > 300px) { .card { font-size: 0.9em; }}
/* Реагирует только на контейнер с именем main */@container main (width > 600px) { .card { font-size: 1.4em; }}Шортхенд container объединяет имя и тип в одну строку:
/* container: <name> / <type> */.sidebar { container: sidebar / inline-size;}Container Query Units — cqw, cqi и другие
Заголовок раздела «Container Query Units — cqw, cqi и другие»Внутри @container можно использовать специальные единицы измерения, привязанные к размеру контейнера:
| Единица | Значение |
|---|---|
cqw | 1% ширины контейнера |
cqh | 1% высоты контейнера |
cqi | 1% inline-размера контейнера (обычно ширины) |
cqb | 1% block-размера контейнера (обычно высоты) |
cqmin | меньшее из cqi и cqb |
cqmax | большее из cqi и cqb |
Пример — шрифт масштабируется плавно вместе с контейнером:
@container (width > 300px) { .card h2 { /* font-size растёт вместе с контейнером */ font-size: max(1.2em, 1em + 2cqi); }}Интерактивный пример 1 — базовые container queries
Заголовок раздела «Интерактивный пример 1 — базовые container queries»Перетащи ползунок, чтобы изменить ширину контейнера и увидеть, как карточка меняет layout:
Интерактивный пример 2 — именованные контейнеры
Заголовок раздела «Интерактивный пример 2 — именованные контейнеры»Один и тот же компонент .card в двух разных контейнерах — sidebar и main. Каждый контейнер настроен независимо:
Интерактивный пример 3 — Container Query Units (cqi)
Заголовок раздела «Интерактивный пример 3 — Container Query Units (cqi)»Единицы cqi позволяют шрифту и элементам плавно масштабироваться вместе с контейнером — без медиа-точек: