Skip to Content
CSSАдаптив и единицы

Адаптив и единицы

Уровень: middle. Container queries ближе к senior.

Вопрос

От чего считаются rem, em и vw, и чем медиазапрос отличается от контейнерного?

Короткий ответ

px — одна CSS-единица, не физический пиксель экрана. em считается от размера шрифта элемента, у margin и padding тоже от шрифта, не от ширины. Вложенные em перемножаются. rem всегда от корня, html. Им задают отступы и типографику, чтобы масштаб от пользовательского размера шрифта сохранялся.

% — от содержащего блока. vw и vh — от вьюпорта. vh на мобильных врёт из-за панели браузера. Для видимой области ближе dvh и svh.

Медиазапрос смотрит на вьюпорт или характеристики устройства: ширина окна, prefers-reduced-motion, prefers-color-scheme. Контейнерный запрос @container смотрит на размер родителя, помеченного container-type. Один и тот же карточный компонент может стать колонкой в узкой панели и строкой в широкой, хотя окно браузера большое.

Разбор

Mobile first: базовые стили для узкого экрана, min-width добавляет правила для больших. Так меньше переопределений. Брейкпоинт ставят по слому макета, не по названию телефона.

Картинкам задают max-width: 100% и осмысленные width / height или aspect-ratio, чтобы загрузка не прыгала вёрстку. Это вклад в CLS.

clamp(min, preferred, max) склеивает резинку и потолок: font-size: clamp(1rem, 2vw, 1.5rem). Предпочтительное значение растёт с экраном, крайние не дают тексту стать пылью или плакатом.

Контейнер:

.panel { container-type: inline-size; } @container (min-width: 30rem) { .card { flex-direction: row; } }

На что смотрят на senior

Контейнерный запрос не заменяет медиазапрос для вещи, которая правда про окно: число колонок всей страницы, показ бокового меню. Его берут для компонента, который живёт в разных по ширине слотах.

Анимация width и height гоняет layout. Для движения ближе transform и opacity: их чаще поднимают на композитор. prefers-reduced-motion: reduce отключает или упрощает анимацию. Это проверяют так же, как контраст.

100vw включает ширину скроллбара и даёт горизонтальный скролл. Для полной ширины секции обычно хватает width: 100% у блока в потоке.

Типичные ошибки

  • Задать всю типографику в px и сломать увеличение шрифта в браузере.
  • Копить вложенные em и получить непредсказуемый размер.
  • Вешать брейкпоинт компонента на ширину окна, когда он лежит в узкой колонке.
  • Анимировать height: auto и удивляться рывку. Для раскрытия считают высоту или используют grid-строку 0fr / 1fr.

Задача

Корень html имеет font-size: 16px. У карточки font-size: 2rem, у вложенного span внутри неё padding: 1em. Чему равен padding?

Показать ответ

rem считается от корня: 2rem это 32px, таким будет шрифт карточки.

em у padding считается от шрифта самого элемента. Если у span размер не переопределён, он наследует 32px, и 1em padding равен 32px, не 16px.

Last updated on