Урок 37. Теория: Адаптивная типографика и отступы

📁 Раздел: Адаптивная вёрстка ⏱️ Время изучения: ~70 мин 🎯 Сложность: Средняя
#clamp #min #line-height

⚡ Кратко

Fluid-типографика — это размеры, которые плавно растут вместе с шириной экрана, без скачков на breakpoint. Главный инструмент — функция clamp(min, preferred, max).

  • clamp() берёт предпочтительное значение (обычно с vw), но не даёт ему упасть ниже min и подняться выше max.
  • font-size: clamp(2rem, 5vw, 4rem) — заголовок никогда не мельче 2rem и не крупнее 4rem.
  • Относительные единицы: rem — от корня, em — от родителя, ch — ширина символа «0», vw — 1% ширины окна.
  • Длину строки ограничивай через max-width: 60ch — комфортные ~45–75 символов.
  • Отступы тоже делают fluid через clamp() и хранят в CSS-переменных — общий ритм страницы.

Главная идея

До clamp() адаптивный размер шрифта писали так: фиксированное значение плюс лесенка из @media-запросов. На каждом breakpoint размер «прыгал» ступенькой. Fluid-типографика убирает ступеньки: размер меняется плавно вместе с шириной окна, но остаётся в заданных границах.

Сердце темы — CSS-функция clamp(min, preferred, max). Она принимает три значения и возвращает среднее: пока preferred находится между min и max — вернётся именно оно; если опустилось ниже min — вернётся min; если поднялось выше max — вернётся max. Чтобы значение реагировало на ширину окна, в preferred подмешивают единицу vw (1vw = 1% ширины viewport).

clamp() — это термостат с минимумом и максимумом. Ты задаёшь «комфортную температуру» (preferred — она следует за погодой за окном, то есть за шириной экрана), но выставляешь и пределы: не холоднее min и не жарче max. Как бы ни менялась «погода» (viewport), термостат не даст шрифту стать ни мышиным мелким, ни гигантским — он держит размер в разумной вилке.

Как работает clamp() при изменении ширины окна

Если построить график «размер шрифта от ширины окна», получится характерная фигура: плоско → наклон → плоско. Слева ширина мала — работает min (горизонтальная полка). В середине размер линейно растёт вместе с vw (наклон). Справа окно широкое — включается max (вторая полка).

размер ширина окна min max min vw (наклон) max
clamp(min, …vw…, max): шрифт «прилипает» к min на узких экранах, растёт по vw в середине, упирается в max на широких.

Относительные единицы — фундамент

Fluid-вёрстка держится на относительных единицах. Каждая отвечает за свой контекст:

  • rem — относительно корневого font-size (обычно 16px). 1.5rem = 24px. Главная единица для размеров: меняешь корень — масштабируется всё.
  • em — относительно font-size текущего элемента. Удобно для отступов внутри компонента, но вложенность умножает значения, и легко запутаться.
  • ch — ширина символа «0» текущего шрифта. max-width: 60ch ≈ 60 символов в строке — точный инструмент для комфортной длины строки (measure).
  • vw / vh — 1% ширины / высоты viewport. Делают значение «текучим», но без границ опасны — поэтому их прячут внутрь clamp().

Когда применять, а когда нет

Fluid-типографику применяют к крупным элементам: заголовкам hero, ключевым числам, лид-абзацам. Там плавный рост выглядит выигрышно. Не делай fluid весь body-текст: основной читаемый текст комфортнее с понятным стабильным размером (например clamp(1rem, …, 1.125rem) с очень узкой вилкой).

То же касается отступов: fluid spacing через clamp() в CSS-переменных (--space-section, --space-card) даёт единый ритм — поля секций сжимаются на телефоне и раскрываются на десктопе. Это и есть модульная шкала: набор согласованных шагов (--step-0--step-5), каждый — отдельный clamp().

Зачем переменные: объявив шкалу один раз в :root, ты ссылаешься на var(--step-4) вместо повторения clamp(...) в каждом правиле. Поменять масштаб всего сайта — значит поправить 6 строк, а не 60.

Частая ошибка

Самая распространённая ловушка — font-size: 5vw без clamp(). На узком телефоне это даёт нечитаемо мелкий шрифт, а на 4K-мониторе — баннерные буквы. Всегда оборачивай vw в clamp() с разумными min/max.

Базовый CSS

📄 lesson-37/styles.css
:root {
  /* модульная шкала размеров: каждый шаг — свой clamp() */
  --step-0: clamp(1rem, 0.96rem + 0.2vw, 1.125rem);  /* body */
  --step-5: clamp(2.25rem, 1.4rem + 4vw, 5rem);      /* hero h1 */

  /* fluid spacing — единый ритм отступов */
  --space-section: clamp(3rem, 8vw, 7rem);
  --space-card: clamp(1rem, 2vw, 2rem);
}

.hero {
  padding-block: var(--space-section);
}

.hero h1 {
  max-width: 12ch;          /* короткий заголовок не растягивается */
  font-size: var(--step-5);
  line-height: 1;
}

.lead {
  max-width: 65ch;          /* комфортная длина строки */
  font-size: var(--step-0);
  line-height: 1.6;
}

Навигация