Truncate
.truncate — clamping text to one line, or to N lines, with an ellipsis.
Examples
A single line that is longer than its box, so it ends in an ellipsis rather than wrapping.
Three lines of an excerpt, and then an ellipsis. The number of lines is a custom property, so there is no class per number.
<p class="truncate">A single line that is longer than its box, so it ends in an ellipsis rather than wrapping.</p>
<p class="truncate-lines" style="--truncate-lines: 3">Three lines of an excerpt, and then an ellipsis. The number of lines is a custom property, so there is no class per number.</p>Truncation is purely visual: the whole string stays in the DOM, so a screen reader announces all of it while a sighted reader sees three words.
Fine for a preview whose full text is one interaction away; a defect for anything that is the only copy of a value.
This one truncates.
<div style="display: flex; gap: 1rem">
<p class="truncate" style="min-inline-size: 0">This one truncates.</p>
</div>A flex or grid child refuses to shrink below its content without min-inline-size: 0, so there is nothing to overflow and nothing truncates. It is the single most common reason this "doesn’t work".
Tokens 1
Level 2, declared on .truncate itself. Set any of them on that selector to restyle this utility without touching the skin.
| Token | Default |
|---|---|
| --truncate-lines | 2 |
Variants and states
Variants
None. It is one shape, and the page does the rest.
Inside it
.truncate-lines
State it reads
None.
Before you ship it
What you have to do 4 requirements
- Truncation needs a box narrower than its text. An element that sizes to its own content never overflows, so nothing is ever clipped:
- A flex or grid child needs
min-inline-size: 0. The automatic minimum size of a flex or grid item is its content, so it refuses to shrink and the text blows the layout wide instead of being clipped. This is the single most common reason truncation "does not work", and it does not look like a missing property — it looks like a broken layout. Both classes set it on themselves, so a.truncatethat is the flex child needs nothing. If the truncated text sits inside a wrapper and the wrapper is the flex child, the wrapper needs it and nothing here can reach that element. Measured: a wrapper without it left the text 622px wide inside a 300px row, in all three engines. - The element must not be inline.
overflowandtext-overflowdo nothing on a non-replaced inline box, so.truncateon a bare<span>in running text is silently inert. Put it on a block-level element — inside a table cell that means a<div>, not a<span>. - A table cell needs
table-layout: fixedon the table. Anautotable widens to fit its content and the clip never happens. The class goes on a block-level child of the cell, not on the<td>: a cell ignoresoverflow.
src/css/utilities/truncate.css · npx mostlycss add truncate