Проблема статической типографики
На протяжении первого десятилетия адаптивного веб-дизайна большинство команд использовали 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) |
| H2 | 1.375rem (22px) | 2rem (32px) | clamp(1.375rem, 1.15rem + 1.07vw, 2rem) |
| H3 | 1.125rem (18px) | 1.5rem (24px) | clamp(1.125rem, 1rem + 0.54vw, 1.5rem) |
| Body | 1rem (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() с графиком.