This proposal is an early design sketch by Blink Layout Team in Google to describe the problem below and solicit feedback on the proposed solution. It has not been approved to ship in Chrome.
- Introduction
- Goals
- Non-goals
- Use cases
- [Potential Solution]
- Detailed design discussion
- Considered alternatives
- References & acknowledgements
In text layout, web authors want to align the lines with both ends of the container, but web authors want to achieve this by adjusting the font size instead of justification. Currently, there is no such method in CSS, and the only option is to manually adjust the font size through trial and error or using JavaScript.
Web authors want to fit the text into a container of a specific size without it overflowing. For example, if the container width is narrow and a long word inevitably overflows the container, web authors want to reduce the font size to make it fit within the container. Web authors want to avoid text overflowing the container due to unexpectedly long words used in text translations or when end-users provide arbitrary text.
A CSS solution elevates "fit-width text" from a complex, potentially janky scripting problem to a fundamental, performant, and easy-to-use aspect of the CSS layout system.
JavaScript solutions for fitting text typically involve reading element dimensions (layout reads), calculating new styles (computation), and writing new styles (layout writes). When triggered frequently (e.g., during window resizing, container resizing via ResizeObserver, or dynamic content loading), this read-compute-write cycle can lead to layout thrashing, causing jank, slow rendering, and high CPU usage. A native CSS implementation can integrate the text fitting calculation directly into the browser's existing layout and rendering pipeline. This means the fitting happens efficiently as part of the initial layout or subsequent reflows, without the overhead and potential timing issues of stepping in and out of JavaScript.
JavaScript-based fitting often suffers from a "flash of unstyled content" or a visible "jump" or reflow as the text is initially rendered at one size and then resized by the script. By making text fitting a native layout property, the browser can calculate the final size/scale before or during the initial paint, resulting in text that appears correctly sized and positioned from the start, providing a much smoother and more professional user experience. This will also improve the quality of the FCP.
Achieving robust text fitting in JavaScript is complex. It requires handling initial load, window resizes, container resizes, potential font loading issues, minimum/maximum size constraints, different fitting methods (font size vs. scaling), and managing the state across various elements. A declarative CSS solution allows developers to achieve the desired behavior with a simple property declaration, significantly reducing the amount of code they need to write, test, and maintain. It integrates seamlessly into the CSS cascade, can be easily controlled by media queries or container queries, and reduces the reliance on complex imperative logic.
- Provides a way to align both ends of the text with the width of the container. Consider both cases: fitting by enlarging the text and fitting by shrinking the text.
- Provide a way to adjust the container width to match to the widest line.
- Provide a way to adjust font size to fit text to the container's width and height.
- Introduce a new line-wrapping algorithm to fit lines to the container width.
Publishing (news sites, blogs, magazines, portfolios) heavily relies on flexible and visually appealing typography that adapts to various layouts and screen sizes. This feature is highly relevant here, particularly for fluid & responsive headlines. This includes:
A short headline for a prominent article might look lost in a wide column on a desktop, text-grow could automatically increase its size or character/word spacing to fill the available width, creating a stronger visual impact without manual tweaking or JS calculations based on breakpoints.
- Original:
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et ...

- A) Enlarge each line to fit them to the container width:

- B) Enlarge all lines to fit the widest line to the container width:

A long headline containing several words or a very long word might easily overflow its container on smaller screens or in constrained sidebar layouts. Text-shrink ensures the headline reduces its size or adjusts spacing to fit within the allocated width, preventing truncation or awkward line breaks without needing JS to measure and resize.
- Original:
<div>Effective CSS architecture emphasizes componentization for easier ...

- A) Making an overflowing line smaller to fit it to the container width:

- B) Making all lines smaller to fit the overflowing line to the container width:

Text accompanying images or used as pull quotes often needs to precisely fit the width of the related content block. 'Shrinking' can prevent overflow, while 'Expanding' can be used to ensure short captions don't look awkward in wide containers.
For certain stylistic layouts, ensuring paragraphs or short text blocks align perfectly to the container's left and right edges by subtly adjusting spacing or size can be achieved declaratively with these properties, rather than relying on justified text which can sometimes lead to excessive gaps.
We'd like to introduce a new CSS property.
- Name:
'
text-fit' - Value:
<fit-type> <fit-target>? <scale-limit>? - Initial: none
- Applies to: text containers
<fit-type> = none | grow | shrink
grow: Allow lines to fit the target container width by enlarging text.shrink: Allow lines to fit the target container width by shrinking text.
<fit-target> = consistent | per-line | per-line-all
consistent: Makes all lines in the target container larger/smaller by a scaling factor for the widest line.per-line: Makes each line in the target container larger/smaller independently, except for the last line.per-line-all: Make each line in the target container larger/smaller independently, including the last line.
<scale-limit> = <percentage>
The maximum scaling factor for grow, or the minimum scaling factor for shrink.
text-fit: grow per-line-all;See Use cases Expanding A. If a line width is narrower than the container width, line's font-size is increased so that the line width matches the container width. Even if a single font-size is used in the container, each line might have different font-sizes. If a line width is wider than the container width, the line is unchanged.
text-fit: grow per-line-all 200%;Ditto. However the text will expand up to twice the original size. So, lines might be narrower than the container width.
text-fit: grow consistent;See Use cases Expanding B. Compute a scaling factor so that the widest line in the container fits to the container width, and scale all lines in the container by the scaling factor. If the widest line is wider than the container width, nothing happens.
text-fit: shrink per-line-all;See Use cases Shrinking A. If a line width is wider than the container width, line's font-size is decreased so that the line width matches the container width. Even if a single font-size is used in the container, each line might have different font-sizes. If a line width is narrower than the container width, the line is unchanged.
text-fit: shrink per-line-all 50%;Ditto. However the text will shrink down to half the original size. So lines might be wider than the container width.
text-fit: shrink consistent;See Use cases Shrinking B. Compute a scaling factor so that the widest line in the container fits to the container width, and scale all lines in the container by the scaling factor. If the widest line is narrower than the container width, nothing happens.
- Items contained in a line box are classified as either "scalable" or "static", and only "scalable" items are affected by this feature.
- See w3c/csswg-drafts#12888.
- All texts are scalable even if a text has a font-size diffrent from the container font-size.
- %-based
letter-spacingandword-spacingare scalable. - Replaced elements such as
<img>and<input>are static. - Atomic inlines are static
padding,border, andmarginfor inline direction are static.- This classification may be configurable in the future.
- How does this interact with properties with
<length>.- Should the
<length>be scaled or not? See w3c/csswg-drafts#12888. - In general,
<length>values are not scaled.4pxshould be4pxeven if a line is scaled. Font-relative length units such asemare not scalable too. Exceptionally, the percentage values of some CSS properties should be linked to the rendered font size, so they are scalable.
- Should the
- Accessibility: See w3c/csswg-drafts#12886.
- Text decoration, emphasis marks, ruby annotations should work well with scaled font-size.
- This feature should not affect the container's intrinsic size.
- Implement this behavior as a value of font-size property, like
font-size:fit-width. It's technically difficult because the container width might depend on the font-size.