Главная идея
До 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 (вторая полка).
Относительные единицы — фундамент
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
: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;
}