После восьми лет ожиданий у CSS наконец появилось нативное средство масштабировать
текст под ширину контейнера. Никакого JavaScript, никаких угадаек с clamp(),
никакого ручного подбора. Всё, что нужно знать — здесь.
Каждый веб-разработчик сталкивался с этой проблемой: есть заголовок, название карточки или цитата, которые должны растягиваться на всю ширину контейнера — но текст либо слишком короткий (оставляя неловкие пустоты), либо слишком длинный (переполняя контейнер или неравномерно переносясь).
Традиционные решения — все болезненные. Можно использовать clamp() с вьюпорт-единицами
в надежде на лучшее — угадайка, которая ломается на каждом разрешении. Можно подключить
FitText.js — JavaScript-решение на 50+ строк, вызывающее layout thrashing и мерцание
нестилизованного текста (FOUC). Или можно провести полдня, вручную подгоняя размеры шрифтов
в CSS, чтобы потом обнаружить, что одна переведённая строка (вроде немецкого заголовка там,
где английский укладывался в 40 символов) ломает всю вёрстку.
CSS text-fit наконец решает эту проблему. Поставляемый в Chrome 150
(Desktop, Android и WebView), это свойство встраивает масштабирование шрифта непосредственно
в конвейер компоновки браузера. Браузер измеряет каждую строку текста и автоматически
подстраивает размер шрифта так, чтобы текст заполнял контейнер — с тонким контролем
над тем, как и насколько.
Свойство text-fit масштабирует размер шрифта текста, чтобы он помещался по
ширине содержащего его блока. Оно определено в спецификации CSS Text Level 4
(Working Draft) и было предложено командой Blink Layout в Google.
Что делает text-fit особенным — это когда происходит масштабирование:
браузер встраивает вычисление подгонки непосредственно в свой layout-проход. Здесь нет
JavaScript-цикла «чтение-вычисление-запись», нет накладных расходов ResizeObserver
и — самое главное — нет мерцания нестилизованного контента. Текст отображается в финальном
размере уже при первой отрисовке.
Разработчики требовали это свойство почти десять лет. Issue #2528 в CSSWG под названием «Feature for making text always fit the width of its parent» был создан в апреле 2018 года Тоби Райфом и накопил 123 комментария и 115 реакций «👍» за восемь лет. Он был закрыт с резолюцией «Closed Accepted by CSSWG Resolution» — то есть рабочая группа согласилась, что эта функция стоит спецификации и реализации.
Свойство text-fit принимает до трёх компонентов:
text-fit: <fit-type> <fit-target>? <scale-limit>?;
Управляет направлением масштабирования:
| Значение | Поведение |
|---|---|
none |
По умолчанию. Масштабирование не применяется. |
grow |
Увеличивает текст, который короче ширины контейнера, чтобы он заполнил пространство. |
shrink |
Уменьшает текст, переполняющий контейнер, чтобы он помещался по доступной ширине. |
Управляет масштабированием многострочного текста:
| Значение | Поведение |
|---|---|
consistent |
Вычисляет единый коэффициент масштабирования для самой широкой строки и применяет его равномерно ко всем строкам. Сохраняет относительные пропорции между строками. |
per-line |
Каждая строка масштабируется независимо, кроме последней. Полезно для заголовков, где последняя строка должна выглядеть естественно короче. |
per-line-all |
Каждая строка, включая последнюю, масштабируется независимо для заполнения ширины контейнера. Создаёт наиболее равномерный внешний вид. |
Процент, ограничивающий максимальное увеличение или уменьшение шрифта. Для grow
это максимальный масштаб (например, 200% = не более 2x от исходного размера). Для
shrink это минимальный масштаб (например, 50% = не менее половины
исходного размера). Если значение опущено, лимита нет.
Самый частый сценарий: заголовок, который короче своего контейнера. С
text-fit: grow per-line-all каждая строка расширяется независимо,
заполняя всю ширину:
<h1 style="text-fit: grow per-line-all;">
Short Headline
</h1>
Каждая строка, которая уже контейнера, получает увеличенный font-size,
пока текст не заполнит всю ширину. Строки, которые уже помещаются, остаются без изменений.
Ещё одна частая проблема: текст, выходящий за пределы контейнера на маленьких экранах или в плотных макетах. Это особенно актуально для пользовательского контента, переведённого текста или динамических данных:
.card-title {
font-size: 1.25rem;
text-fit: shrink per-line 50%;
}
Это уменьшает любые переполняющие строки, чтобы они помещались в контейнер, минимум до 50%
от исходного размера 1.25rem. Режим per-line означает,
что последняя строка остаётся нетронутой — приятная деталь, сохраняющая естественный
типографический ритм.
Когда нужно масштабировать все строки вместе (сохраняя их относительное соотношение
размеров), используйте consistent:
.hero-title {
font-size: 2.5rem;
text-fit: grow consistent 200%;
max-width: 800px;
}
Браузер вычисляет коэффициент масштабирования из отношения самой широкой строки к ширине контейнера, а затем применяет тот же коэффициент ко всем строкам. Это предотвращает ситуацию, когда одна короткая строка раздувается, а длинная остаётся мелкой — пропорции остаются естественными.
Подписи к изображениям, figcaption и аннотации — классические кандидаты на переполнение, потому что их контейнер обычно имеет фиксированную ширину:
figcaption {
font-size: 0.9rem;
text-fit: shrink per-line-all 50%;
}
Это гарантирует, что подпись всегда помещается в контейнер, уменьшаясь только когда
это действительно необходимо. На широких контейнерах текст отображается в полном размере
0.9rem.
Вот где text-fit действительно блистает. Представьте сайт, отображающий
один и тот же заголовок на нескольких языках — английский может идеально помещаться
в 2rem, но немецкий может быть на 40% длиннее, а японский — намного короче:
.product-headline {
font-size: 2rem;
text-fit: shrink per-line 50%;
/* Также работает: text-fit: grow per-line-all 150%; для коротких языков */
}
Один и тот же CSS работает для всех переводов. Длинный немецкий текст уменьшается,
чтобы поместиться; короткие английские заголовки могут альтернативно использовать
grow для заполнения пространства. Никаких языковых переопределений.
Разработчики годами обходили эту проблему. Вот как
text-fit соотносится с альтернативами:
| Техника | FOUC? | Layout Thrashing? | Учитывает контейнер? | Сопровождение |
|---|---|---|---|---|
| text-fit | Нет | Нет | Да | Одна строка CSS |
| FitText.js / JavaScript | Да (FOUC) | Да | Да | 50+ строк JS |
| clamp() + vw-единицы | Нет | Нет | По вьюпорту | Ручная настройка |
| text-align: justify | Нет | Нет | Да | Добавляет пробелы, не размер |
Ключевое преимущество — интеграция с движком компоновки браузера.
JavaScript-решения вроде FitText.js работают так: читают размеры элемента, вычисляют
коэффициент масштабирования и записывают его обратно — классический цикл чтение-вычисление-запись,
вызывающий layout thrashing, если его аккуратно не дебаунсить через requestAnimationFrame.
Они также создают видимый FOUC: текст сначала отображается в исходном размере, а затем
скачком переходит к подогнанному размеру после выполнения JavaScript.
С text-fit браузер знает размеры контейнера во время layout-прохода и
подстраивает размер шрифта до первой отрисовки. Результат: ноль FOUC, ноль layout
thrashing и ноль JavaScript.
clamp() с вьюпорт-единицами избегает обеих проблем — это нативный CSS без
FOUC и thrashing — но он фундаментально основан на размере окна, а не контейнера.
Заголовок в боковой панели шириной 300px на экране 1920px получает то же значение
clamp(), что и заголовок в основной колонке шириной 600px.
text-fit работает с реальным контейнером, что делает его правильным
инструментом для карточных UI, боковых панелей и любых компонентных дизайн-систем.
Вот в чём загвоздка. По состоянию на июнь 2026 года text-fit — это
фича только для Chrome. Полная матрица совместимости:
| Браузер | Версия | Статус |
|---|---|---|
| Chrome (Desktop) | 150+ | Доступен |
| Chrome (Android) | 150+ | Доступен |
| Chrome (WebView) | 150+ | Доступен |
| Chrome (iOS) | — | Недоступен |
| Edge | 150+ | Доступен (Chromium) |
| Opera / Brave | 150+ | Доступен (Chromium) |
| Firefox | — | Нет сигнала |
| Safari | — | Нет сигнала |
Firefox имеет открытый issue стандартизации (#1377) без решения. Safari имеет похожий WebKit issue (#637). Также открыт TAG design review.
Поскольку пользователи Firefox и Safari не увидят эффекта, необходимо предусмотреть fallback.
Правило @supports — идеальный инструмент:
/* Fallback для всех браузеров: используем clamp() с обработкой переполнения */
.headline {
font-size: clamp(1.5rem, 4vw, 3rem);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* Progressive enhancement для Chrome 150+ */
@supports (text-fit: grow) {
.headline {
text-fit: grow per-line-all 200%;
overflow: visible;
text-overflow: clip;
white-space: normal;
}
}
Этот паттерн даёт каждому браузеру работоспособный опыт. Пользователи Chrome получают
полный эффект text-fit с точной подгонкой под контейнер. Пользователи Firefox
и Safari получают адаптивный размер через clamp(), который достаточно хорош
и не ломается. По мере расширения поддержки браузерами блок @supports
автоматически активируется на новых браузерах — без изменений кода.
Заголовков в карточках. Цитат в боковых панелях. Подписей к изображениям. Многоязычных текстовых систем. Hero-секций. Кнопок призыва к действию. Анимированных текстовых блоков.
Основного текста (страдает читаемость). Элементов фиксированного размера. Печатных макетов. Контента, зависящего от скринридеров. Окружений, требующих text-align-last: justify.
h1 { text-fit: grow per-line-all; } заставляет каждый заголовок,
независимо от длины, заполнять всю ширину колонки.
text-fit: shrink per-line-all 50%
гарантирует, что они никогда не выйдут за пределы, оставаясь читаемыми.
text-fit: grow consistent 200%
масштабирует весь блок равномерно.
text-fit: shrink per-line обрабатывает переполнение,
оставляя последнюю строку визуально отличимой.
Реализация text-fit потребовала более 85 изменений кода (CL) в кодовой базе
Chromium, с Finch-экспериментом под кодовым именем CssTextFit.
Web Platform Tests доступны на
wpt.fyi.
text-fit масштабирует font-size текстовых узлов. Вот на что
это влияет:
Масштабируется: Весь текстовый контент, процентные значения
letter-spacing и word-spacing, текстовые декорации, знаки
ударения и ruby-аннотации. Всё это масштабируется пропорционально изменению размера шрифта.
Не масштабируется: Изображения (<img>), элементы форм
(<input>), атомарные строчные элементы, padding/border/margin по строчной
оси и значения с фиксированной длиной (включая единицы em на не-текстовых
свойствах). Эта классификация может стать настраиваемой в будущем.
text-fit влияет только на подгонку по ширине. Он не ограничивает
высоту текста. Если нужна подгонка по обоим измерениям, всё ещё требуется JavaScript.
CSSWG обсуждал подгонку по высоте, но она не запланирована.
Он также не влияет на внутренний размер контейнера. Подгонка применяется
как финальный шаг в layout-проходе, поэтому она не изменит позиционирование других элементов
относительно контейнера. Свойства переноса текста вроде white-space
и word-break вычисляются первыми — text-fit работает с
результирующими строками.
Существует открытый issue CSSWG (#12886), который ставит под вопрос доступность
text-fit, особенно режима shrink. Если текст уменьшается
слишком сильно, он становится нечитаемым — особенно для пользователей с нарушениями зрения.
Команда Chromium в Intent to Ship отмечает, что «потенциальное изменение лишь незначительно увеличит размер шрифта» — риск поломки сайтов низок. Однако, как ответственный разработчик, вы должны:
Я делаю современную адаптивную вёрстку
scale-limit для shrink (например, 50%),
чтобы текст не становился микроскопическим.text-fit: shrink на основном тексте или любом контенте, который
должен соответствовать рекомендациям WCAG по контрасту и размеру.@supports, чтобы пользователи не-Chrome браузеров
видели читаемый текст, размеренный вашими fallback-правилами.
CSS text-fit — одна из тех редких возможностей, после которых удивляешься,
как мы вообще жили без неё. Она решает действительно болезненную проблему — подгонку
текста под контейнер — чистым, нативным решением без единой строчки JavaScript.
Ограничение только Chrome — реальное сдерживающее обстоятельство сегодня, но паттерн
@supports делает его безопасным для использования в качестве
progressive enhancement.
Если вы начинаете новый проект с Chrome-based инструментарием (Electron-приложения,
внутренние дашборды или Chromium-киоски), text-fit готов к продакшену
уже сейчас. Для публичных сайтов его стоит добавлять как progressive enhancement —
пользователи Chrome получают отполированный опыт, все остальные — надёжный fallback.
Web Platform Tests доступны на wpt.fyi, спецификация в CSS Text Level 4, и 85+ патчей Chromium уже поставляются. Будущее контейнер-ориентированной типографики начинается здесь.
Работаете над веб-приложением, которому нужна продуманная архитектура и чистый код? Я открыт для фриланс-проектов — давайте обсудим, что вы строите.