Сделай компоненты отзывчивыми к своему контейнеру, а не к вьюпорту, и структурируй таблицы стилей нативной вложенностью.
Открыть этот урок в KodokonМедиазапросы измеряют вьюпорт: карточка, которая показывается и в узкой боковой панели, и в основной сетке, не может корректно подстроиться с их помощью, потому что одна и та же ширина экрана соответствует двум разным контекстам. Контейнерные запросы снимают эту связку: компонент спрашивает про размер своего контейнера. Необходимое условие: явно назначить контейнер через container-type (inline-size, чтобы измерять только горизонтальную ось - самый частый случай), при желании дав ему имя через container-name.
.sidebar {
container-type: inline-size;
container-name: sidebar;
}
@container sidebar (min-width: 400px) {
.widget {
display: grid;
grid-template-columns: 80px 1fr;
gap: 12px;
}
}Контейнерные единицы дополняют картину: 1cqi равен 1% инлайнового размера запрашиваемого контейнера (есть также cqw, cqh, cqb, cqmin, cqmax). В связке с clamp() они дают плавную типографику для каждого компонента: одна и та же карточка получает заголовок, соразмерный её колонке, где бы она ни оказалась.
.card-slot {
container-type: inline-size;
}
.card h2 {
font-size: clamp(1rem, 5cqi, 1.75rem);
}
@container (max-width: 300px) {
.card .meta {
display: none;
}
}Нативная вложенность наконец приносит вложенность без препроцессора. Селектор & ссылается на родительский контекст; медиазапросы и @container вкладываются прямо внутрь правила. Ключевое отличие от Sass: вложенный родитель трактуется так, будто он обёрнут в :is(). Два следствия: специфичность родителя равна специфичности самого сильного из его селекторов, если это список, а & .child не выполняет склейку строк - паттерна Sass &__element для генерации имён BEM нативно не существует.
.menu {
display: flex;
gap: 8px;
& > li {
list-style: none;
&:hover {
background: #f3f4f6;
}
}
@media (min-width: 768px) {
gap: 16px;
}
}5cqi?