
Руководство по CSS clamp(): адаптив без медиа-запросов
В этой статье разбираем clamp(), функцию CSS, которая задаёт значение с нижней
и верхней границей. Это удобно для адаптивной вёрстки, особенно для font-size,
padding и margin. С clamp() типографика плавно тянется за шириной экрана,
и медиа-запросы для этого не нужны вовсе.
Что такое clamp()?
CSS функция clamp() позволяет установить значение, которое адаптируется в
заданном диапазоне в зависимости от ширины экрана.
Как это работает
Первым аргументом идёт наименьшее допустимое значение, вторым динамическое
(обычно с vw), третьим наибольшее допустимое.
Практические примеры
1. Адаптивные заголовки
Этот заголовок:
- Не будет меньше 32px (2rem)
- Масштабируется с шириной экрана и при zoom страницы
- Не превысит 64px (4rem)
2. Плавные отступы
Не используйте только vw в среднем значении, как в clamp(1rem, 3vw, 3rem).
Единица vw зависит от ширины viewport и не реагирует на масштабирование
страницы (Ctrl/Cmd + или колёсико мыши). При увеличении масштаба размер не
изменится, а это бьёт по доступности. Комбинируйте vw с относительными
единицами: 1rem + 2vw.
3. Адаптивная ширина контейнера
Формула для идеального clamp()
Для расчёта оптимальных значений используйте формулу:
Пример расчёта
- Минимальный размер: 16px при 320px viewport
- Максимальный размер: 24px при 1200px viewport
Коэффициент масштабирования: (24 − 16) / (1200 − 320) = 0.00909 → 0.909vw. Базовое значение: 16 − 0.00909 × 320 = 13.09px → 0.818rem.
Проверьте себя: при 320px получится ровно 16px, при 1200px ровно 24px. Если подставить одинаковые числа в оба слагаемых (частая опечатка), кривая уедет и на 320px выйдет 17.5px вместо 16.
Считать это руками необязательно. Калькулятор clamp() подставит числа сам и сразу покажет получившуюся кривую.
Чем удобен clamp()
1. Меньше кода
Вместо множества медиа-запросов:
2. Плавные переходы
Размеры изменяются постепенно, без резких скачков при смене брейкпоинтов.
3. Меньше мест для ошибки
Одна строка вместо набора брейкпоинтов. Меньше кода, который надо поддерживать в
трёх местах. А вот на производительность clamp() не влияет: значение
пересчитывается на каждом кадре ресайза, тогда как медиазапрос переключается
один раз. Выигрыш здесь в поддерживаемости, а не в скорости.
Что учитывать на практике
1. Используйте относительные единицы
2. Тестируйте на разных устройствах
Проверяйте, как выглядят размеры на:
- Мобильных (320-414px)
- Планшетах (768-1024px)
- Десктопах (1280px+)
3. Комбинируйте с CSS переменными
Поддержка браузерами
clamp() работает везде с 2020 года, это Baseline. Никакие запасные значения и
полифилы не нужны, дублировать font-size перед ним не надо.
Распространённые ошибки
1. Неправильный порядок значений
2. Слишком большой диапазон
3. Использование только vw
Продвинутые техники
1. clamp() всегда линеен
Иногда советуют «нелинейное масштабирование через calc()». Это заблуждение.
clamp() умеет только прямую линию между минимумом и максимумом. Если нужна
кривая, придётся разбивать диапазон на несколько отрезков или брать контейнерные
запросы.
2. Адаптивная сетка
3. Анимированные значения
Чистый vw ломает масштабирование
Это самая частая и самая незаметная ошибка.
Единица vw привязана к окну, а не к настройкам пользователя. Человек увеличил
шрифт в браузере, а текст не отреагировал. Формально это провал требования WCAG
1.4.4: страница обязана оставаться читаемой при увеличении до 200%.
Лечится одним слагаемым в rem:
Правило простое. Rem-слагаемое должно давать заметный вклад, ориентир не меньше
половины значения на типичной ширине. Минимум и максимум тоже задавайте в rem,
именно они дают тексту расти при зуме.
cqi вместо vw для компонентов
Карточка в сайдбаре шире не станет, сколько ни расширяй экран. Если размер
должен зависеть от контейнера, а не от окна, берите cqi, то есть 1%
инлайн-размера контейнера.
При зуме контейнер растёт вместе с текстом, поэтому cqi ведёт себя доступнее
vw. Подробнее об этом в статье про
контейнерные запросы.
clamp() и line-clamp — разные вещи
Их постоянно путают, потому что называются похоже.
clamp() — математическая функция, она ограничивает число между минимумом и
максимумом. Работает с размерами, отступами, шириной.
-webkit-line-clamp обрезает текст по числу строк и ставит многоточие. К
clamp() отношения не имеет.
min() и max()
clamp(a, b, c) — это в точности max(a, min(b, c)). Иногда нужна только одна
граница:
Кстати, 100vw включает ширину полосы прокрутки, отсюда классическое
горизонтальное переполнение. Берите 100% или 100dvw.
Заключение
clamp() заменяет пачку медиазапросов одной строкой и растягивает размеры
плавно, без скачков на брейкпоинтах. Кода становится меньше, а поддерживать его
проще. На скорость страницы это не влияет, зато на
оценку Lighthouse косвенно работает: меньше правил,
меньше поводов для сдвигов раскладки.
Что запомнить
clamp()берут для типографики и отступов.- Слагаемое в
remобязательно, иначе текст перестанет реагировать на зум. - Проверяйте результат на 320px, на планшете и на широком мониторе.
- Коэффициенты в уме не считают, для этого есть калькулятор.
Полезные ресурсы
CSS clamp(): адаптивный шрифт без медиазапросов
Задайте минимальный и максимальный размер — калькулятор соберёт clamp(), и шрифт будет плавно тянуться за шириной экрана.
Попробовать



