Проблема статической типографики

На протяжении первого десятилетия адаптивного веб-дизайна большинство команд использовали media queries для управления типографикой: один размер шрифта для мобильных устройств, другой — для планшетов, третий — для десктопа. Этот подход работает, но создаёт два фундаментальных недостатка.

Первый: скачкообразные переходы. При пересечении брейкпоинта заголовок внезапно меняет размер с 28px на 40px — без какой-либо визуальной плавности. Пользователи, использующие устройства с шириной экрана вблизи брейкпоинта, видят либо слишком мелкий, либо слишком крупный текст. Второй: необходимость поддерживать несколько наборов значений в синхронизации, что при работе с токенами дизайн-системы быстро становится трудоёмким.

Fluid Typography: основная идея

Fluid (плавная) типографика решает эти проблемы, позволяя размеру шрифта плавно масштабироваться в зависимости от ширины viewport. Вместо дискретных брейкпоинтов — непрерывная функция от минимального до максимального значения.

Первое поколение решений использовало viewport units (vw): font-size: 4vw. Это работало, но имело критический изъян: при очень узком viewport (320px) текст становился нечитаемо мелким, а при очень широком (2560px) — гротескно огромным. Контроля над минимумом и максимумом не было.

Функция clamp(): современный стандарт

CSS-функция clamp(min, preferred, max), получившая широкую поддержку в браузерах в 2020–2021 годах, элегантно решает проблему. Синтаксис: font-size: clamp(минимум, предпочтительное значение, максимум).

Предпочтительное значение — это формула, обычно включающая viewport unit. Пример: font-size: clamp(1rem, 2.5vw, 2rem). При viewport 320px (320 × 0.025 = 8px) значение падает ниже 1rem, поэтому применяется минимум 1rem (16px). При viewport 1440px (1440 × 0.025 = 36px) значение превышает 2rem (32px), поэтому применяется максимум 2rem. В диапазоне от 640px до 1280px font-size плавно меняется вместе с viewport.

«clamp() — это одна из тех CSS-функций, которые меняют то, как вы думаете о типографике. Больше не нужно выбирать один размер: вы задаёте намерение, и браузер вычисляет детали.»

— Артём Кириленко, аналитик Mirevia

Формула расчёта fluid type

Для точного расчёта предпочтительного значения в clamp() используется следующая формула, предложенная Майком Риттерсом (Mike Ritters) и популяризированная Андрю Сильверсмитом (Andrew Silvers):

preferred = минимум_px + (максимум_px - минимум_px) × (100vw - минимум_viewport_px) / (максимум_viewport_px - минимум_viewport_px)

Упрощённая версия для записи в CSS Custom Properties:

ЭлементMin (320px vp)Max (1440px vp)clamp()
H1 (hero)2rem (32px)4.5rem (72px)clamp(2rem, 1.14rem + 4.29vw, 4.5rem)
H1 страницы1.75rem (28px)3rem (48px)clamp(1.75rem, 1.3rem + 2.14vw, 3rem)
H21.375rem (22px)2rem (32px)clamp(1.375rem, 1.15rem + 1.07vw, 2rem)
H31.125rem (18px)1.5rem (24px)clamp(1.125rem, 1rem + 0.54vw, 1.5rem)
Body1rem (16px)1.125rem (18px)clamp(1rem, 0.96rem + 0.18vw, 1.125rem)

Viewport units: полная карта

vw (viewport width) — 1% от ширины viewport. Наиболее используемый unit для fluid type. vh (viewport height) — 1% от высоты viewport. Применяется для вертикально-ориентированных hero-секций. vmin / vmax — меньшее/большее из vw и vh. Полезны для адаптации к разным ориентациям экрана. dvh, svh, lvh — динамические единицы для мобильных браузеров, учитывающие поведение адресной строки. cqw / cqh — container query units, привязанные к размеру контейнера, а не viewport. Революционный инструмент для компонентного дизайна.

Container Query Typography: следующий уровень

Container Queries (2023, полная поддержка во всех современных браузерах) позволяют масштабировать типографику не относительно viewport, а относительно размера родительского контейнера. Это принципиально меняет компонентный подход: карточка, размещённая в узком sidebar, и та же карточка в широкой основной колонке могут использовать разные размеры шрифта — автоматически, без дополнительных медиа-запросов.

Синтаксис: @container (min-width: 400px) { .card__title { font-size: 1.5rem; } }. Для fluid scaling внутри контейнера используйте cqw единицы в clamp(): font-size: clamp(1rem, 3cqw, 1.75rem).

Типографические токены для адаптивных систем

  • Определите CSS Custom Properties на уровне :root для всех текстовых размеров, используя clamp().
  • Используйте семантические имена токенов: --text-display, --text-h1, --text-body, — не --text-48 или --text-large.
  • Документируйте minViewport и maxViewport в комментариях — это критически важно для поддержки.
  • Проверяйте fluid type при растяжении окна браузера: размер должен изменяться плавно, без скачков.
  • Тестируйте на устройствах с нестандартными viewport: складные телефоны, Surface Pro, MacBook Air M1 (2560×1664).
  • Проверяйте поведение при пользовательском масштабировании браузера: fluid type + rem + zoom должны работать корректно.

Инструменты для генерации fluid type

Utopia.fyi — наиболее популярный онлайн-инструмент. Задаёте базовый размер и шкалу для двух viewport, получаете готовые CSS Custom Properties с clamp(). Разработан Trys Mudford. Type Scale (type-scale.com) — для статических шкал с экспортом в CSS/SCSS. Fluid Type Scale Calculator (royalfig.github.io) — для детальной настройки каждого уровня независимо. CSS Clamp Tool (clamp.font-size.app) — визуальный расчёт clamp() с графиком.

Статья: fluid type в деталях Иерархия Все руководства