After eight years of developer demand, CSS finally has a native way to scale
text to fit its container. No JavaScript, no clamp() guessing games,
no manual trial-and-error. Here's everything you need to know.
Every web developer has faced this problem: you have a headline, a card title, or a pull quote that needs to span the full width of its container — but the text is either too short (leaving awkward whitespace) or too long (overflowing or wrapping unevenly).
The traditional solutions are all painful. You can use clamp() with viewport
units and hope for the best — a guessing game that breaks on every screen size. You can
bring in FitText.js, a 50+ line JavaScript solution that causes layout thrashing and a
flash of unstyled text (FOUC). Or you can spend an afternoon manually adjusting font sizes
in your CSS, only to find that a single translated string (like a German headline where
English had 40 characters) breaks the entire layout.
CSS text-fit finally solves this. Shipping in Chrome 150
(desktop, Android, and WebView), this property integrates font scaling directly into the
browser's layout pipeline. The browser measures each line of text and automatically
adjusts the font size so that the text fills its container — with fine-grained control
over how and how much.
The text-fit property scales the font size of text so that it fits the
width of its containing block. It's defined in the CSS Text Level 4
specification (Working Draft) and was proposed by the Blink Layout Team at Google.
What makes text-fit special is when the scaling happens: the
browser integrates the fitting calculation directly into its layout pass. There's no
JavaScript read-compute-write cycle, no ResizeObserver overhead, and — most
importantly — no flash of unstyled content. The text renders at its final size on the
very first paint.
The property has been demanded by developers for nearly a decade. CSSWG Issue #2528, titled "Feature for making text always fit the width of its parent," was created in April 2018 by Tobi Reif and accumulated 123 comments and 115 thumbs-up reactions over eight years. It was closed with the resolution "Closed Accepted by CSSWG Resolution" — meaning the working group agreed this feature was worth specifying and implementing.
The text-fit property accepts up to three components:
text-fit: <fit-type> <fit-target>? <scale-limit>?;
Controls the direction of scaling:
| Value | Behavior |
|---|---|
none |
Default. No text fitting applied. |
grow |
Enlarges text that's shorter than the container width so it fills the space. |
shrink |
Reduces text that overflows the container so it fits within the available width. |
Controls how multi-line text is scaled:
| Value | Behavior |
|---|---|
consistent |
Computes a single scale factor from the widest line and applies it uniformly to all lines. This preserves the relative proportions between lines. |
per-line |
Each line is scaled independently, except the last line. Useful for headlines where the last line should appear naturally shorter. |
per-line-all |
Every line, including the last, is scaled independently to fill the container width. Creates the most uniform visual appearance. |
A percentage that caps how much the font size can grow or shrink. For grow,
this is the maximum scale (e.g. 200% = at most 2x the original size). For
shrink, this is the minimum scale (e.g. 50% = at least half
the original size). Omitting this value means no limit.
The most common use case: a headline that's shorter than its container. With
text-fit: grow per-line-all, each line expands independently to
fill the full width:
<h1 style="text-fit: grow per-line-all;">
Short Headline
</h1>
Each line that's narrower than the container gets its font-size increased
until the text spans the full width. Lines that already fit are left unchanged.
The other common pain point: text that overflows its container on smaller screens or in tight layouts. This is especially common with user-generated content, translated text, or dynamic data:
.card-title {
font-size: 1.25rem;
text-fit: shrink per-line 50%;
}
This shrinks any overflowing lines to fit the container, down to a minimum of 50%
of the original 1.25rem size. The per-line target means
the last line is left untouched — a nice touch that preserves the natural typographic
rhythm.
When you want all lines to scale together (preserving their relative size
relationship), use consistent:
.hero-title {
font-size: 2.5rem;
text-fit: grow consistent 200%;
max-width: 800px;
}
The browser calculates the scale factor from the widest line's ratio to the container width, then applies that same factor to every line. This prevents one short line from ballooning while a longer line stays small — the proportions stay natural.
Image captions, figcaptions, and annotation text are classic overflow candidates because their container is usually a fixed-width element:
figcaption {
font-size: 0.9rem;
text-fit: shrink per-line-all 50%;
}
This ensures the caption always fits its container, shrinking gracefully only when
needed. On wider containers, the text renders at the full 0.9rem size.
This is where text-fit truly shines. Consider a site that displays the
same headline in multiple languages — English might fit perfectly at 2rem,
but German can be 40% longer, and Japanese can be much shorter:
.product-headline {
font-size: 2rem;
text-fit: shrink per-line 50%;
/* Also works: text-fit: grow per-line-all 150%; for short languages */
}
The same CSS works for all translations. Long German text shrinks to fit; short English
headlines could alternatively use grow to fill the space. No language-specific
overrides needed.
Developers have been hacking around this problem for years. Here's how
text-fit stacks up against the alternatives:
| Technique | FOUC? | Layout Thrashing? | Container-Aware? | Maintenance |
|---|---|---|---|---|
| text-fit | No | No | Yes | One line of CSS |
| FitText.js / JavaScript | Yes (FOUC) | Yes | Yes | 50+ lines of JS |
| clamp() + vw units | No | No | Viewport-based | Manual tuning |
| text-align: justify | No | No | Yes | Adds spacing, not sizing |
The key advantage is integration with the browser's layout engine.
JavaScript-based solutions like FitText.js work by reading element dimensions, computing
a scale factor, and writing it back — a classic read-compute-write cycle that causes
layout thrashing if not carefully debounced via requestAnimationFrame.
They also produce a visible FOUC: the text renders at its original size first, then
jumps to the fitted size once JavaScript runs.
With text-fit, the browser knows the container dimensions during the layout
pass and adjusts the font size before the first paint. The result is zero FOUC, zero
layout thrashing, and zero JavaScript.
clamp() with viewport units avoids both problems — it's native CSS with no
FOUC and no thrashing — but it's fundamentally viewport-based, not container-based.
A headline in a 300px sidebar on a 1920px screen gets the same clamp()
value as one in a 600px main content area. text-fit works on the actual
container, making it the right tool for card UIs, sidebars, and any component-based
design system.
This is the catch. As of June 2026, text-fit is a Chrome-only
feature. Here's the full compatibility matrix:
| Browser | Version | Status |
|---|---|---|
| Chrome (Desktop) | 150+ | Shipping |
| Chrome (Android) | 150+ | Shipping |
| Chrome (WebView) | 150+ | Shipping |
| Chrome (iOS) | — | Not shipping |
| Edge | 150+ | Shipping (Chromium) |
| Opera / Brave | 150+ | Shipping (Chromium) |
| Firefox | — | No signal |
| Safari | — | No signal |
Firefox has an open standards position issue (#1377) with no resolution. Safari has a similar WebKit standards issue (#637). There is also an open TAG design review.
Because Firefox and Safari users won't see the effect, you must provide a fallback.
The @supports rule is the perfect tool:
/* Fallback for all browsers: use clamp() with overflow handling */
.headline {
font-size: clamp(1.5rem, 4vw, 3rem);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* Progressive enhancement for Chrome 150+ */
@supports (text-fit: grow) {
.headline {
text-fit: grow per-line-all 200%;
overflow: visible;
text-overflow: clip;
white-space: normal;
}
}
This pattern gives every browser a usable experience. Chrome users get the full
text-fit effect with precise container fitting. Firefox and Safari users
get a responsive clamp()-based sizing that's good enough but doesn't
break. As browser support expands, the @supports block automatically
activates on new browsers — no code changes needed.
Headlines in card layouts. Pull quotes in sidebars. Image captions. Multi-language text systems. Hero sections. Call-to-action buttons. Animated text reveals.
Body text (readability suffers). Fixed-size elements where text should always be the same size. Print layouts. Screen-reader-dependent content. Environments requiring text-align-last: justify.
h1 { text-fit: grow per-line-all; } makes every headline, regardless
of length, span the full column width.
text-fit: shrink per-line-all 50%
ensures they never overflow while keeping them readable.
text-fit: grow consistent 200%
scales the entire block uniformly.
text-fit: shrink per-line handles overflow while
leaving the last line visually distinct.
The text-fit implementation involved over 85 code changes (CLs) in the
Chromium codebase, with a Finch experiment codenamed CssTextFit. The
Web Platform Tests are available at
wpt.fyi.
text-fit scales the font-size of text nodes. Here's what's
affected:
Scalable: All text content, percentage-based letter-spacing
and word-spacing, text decorations, emphasis marks, and ruby annotations.
These all scale proportionally with the font size change.
Not scaled: Images (<img>), form controls
(<input>), atomic inline elements, padding/border/margin in the inline
direction, and fixed-length values (including em units on non-text properties).
This classification may become configurable in the future.
text-fit only affects width fitting. It does not constrain
text height. If you need text that fits both dimensions, you still need JavaScript.
The CSSWG has discussed height fitting but it's not currently planned.
It also does not affect the container's intrinsic size. The fitting is
applied as a final step in the layout pass, so it won't change how other elements are
positioned relative to the container. Text wrapping properties like white-space
and word-break are evaluated first — text-fit operates on the
resulting lines.
There is an open CSSWG issue (#12886) that questions the accessibility implications
of text-fit, particularly the shrink mode. If text shrinks
too much, it becomes unreadable — especially for users with visual impairments.
The Chromium team's Intent to Ship notes that "a potential change will just slightly increase font size" — the risk of breaking sites is low. However, as a responsible developer, you should:
scale-limit for shrink (e.g. 50%)
to prevent text from becoming microscopically small.text-fit: shrink on body text or any content that needs
to meet WCAG contrast and size guidelines.@supports fallback pattern to ensure non-Chrome users see
readable text sized by your fallback rules.I provide modern responsive web development services
CSS text-fit is one of those rare features that makes you wonder how we
lived without it. It solves a genuinely painful problem — fitting text to its container —
with a clean, native, zero-JavaScript solution. The Chrome-only support is a real
constraint today, but the @supports fallback pattern makes it safe to
use as progressive enhancement.
If you're starting a new project with Chrome-based tooling (Electron apps, internal
dashboards, or Chromium-based kiosks), text-fit is production-ready right
now. For public-facing sites, it's worth adding as progressive enhancement — your
Chrome users get the polished experience, everyone else gets a solid fallback.
The Web Platform Tests are live on wpt.fyi, the spec is in CSS Text Level 4, and Chromium's 85+ patches are already shipping. The future of container-fitting typography starts here.
Working on a web application that needs thoughtful architecture and clean code? I'm available for freelance projects — let's talk about what you're building.