CSS Text Properties Table
| Property | Controls | Field note |
|---|---|---|
text-align | start / end / center / justify | start is the logical value - left breaks RTL layouts, start never does |
text-decoration | underline, line-through + style/color | Shorthand since 2020; underline-offset saves descenders on links |
text-transform | uppercase / capitalize | Changes RENDERING only - copy-paste keeps original case; screen readers may spell all-caps |
letter-spacing | Tracking in em | em-relative survives font-size changes; wide tracking rescues all-caps labels |
line-height | Unitless recommended | Unitless 1.5 inherits as a RATIO; px inherits frozen - the inherited-value trap |
white-space | nowrap / pre / pre-wrap | pre preserves exactly; pre-wrap wraps long lines; nowrap + ellipsis = the one-line clamp |
text-overflow | ellipsis | Dead without its two companions: overflow:hidden AND white-space:nowrap |
overflow-wrap / word-break | break-word vs break-all | break-word breaks only when stuck; break-all breaks anywhere, mid-word |
Text styling fails in predictable pairs: text-overflow: ellipsis does literally nothing unless overflow: hidden AND white-space: nowrap are also set - the three-property combo or no truncation. Learn the pairings once and the confusing one-liner behaviors stop being mysterious.
Bottom line: write text-align: start instead of left (the logical value follows reading direction and survives RTL), keep line-height unitless so it inherits as a ratio that re-scales with each element's font-size, and remember text-transform never edits the text - copy-paste from your UPPERCASE heading yields the original case.
The honest part: justify is a print habit that hurts web readability - rivers of whitespace on narrow columns - and CSS lacks proper hyphenation support in many writing systems, which is exactly why overflow-wrap: break-word (break only when stuck) beats word-break: break-all (break anywhere, mid-word, always).
How to use
- Truncate one line: white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - all three, in that order of importance, plus a title attribute for the full text.
- Set line-height: 1.5 (unitless) on the body once - every element inherits a ratio, so headings and small text each get proportional leading automatically.
- Track all-caps labels: letter-spacing: 0.08em on uppercase text - uniform-height letters read cramped, and em units scale when the label size changes.
Frequently asked questions
Why does my text-overflow: ellipsis not show anything?
Because ellipsis only renders when the text is actually clipped by two other properties: overflow: hidden (cut the box) and white-space: nowrap (never wrap to a second line). Miss either one and the browser either wraps instead of overflowing, or overflows visibly instead of clipping - in both cases ellipsis has nothing to replace. The full pattern is all three declarations together, and for accessibility add title or aria-label with the complete text, since screen readers and sighted users both lose information to truncation.
Why is unitless line-height strongly recommended?
Inheritance mechanics. A px line-height inherits as a frozen number: children with larger fonts keep the parent's line height and collide. A unitless value inherits as a RATIO - each element computes line-height against its own font-size, so headings, body text and captions all get proportionally correct leading from one body rule. The classic bug: body { line-height: 1.4 } is fine, but body { line-height: 20px } breaks the moment a heading at 32px inherits it - the glyphs overlap their own line box.
Does text-transform: uppercase change the underlying text?
No - it is purely a rendering layer. The DOM keeps the original case, so copy-paste, form values, search inside the page and screen readers all encounter the original string. Two consequences: never rely on CSS uppercasing for DATA (store what you mean), and be careful with all-caps styling for long content - many screen readers spell out continuous capitals letter by letter, which is why the accessibility guidance is to use text-transform for short labels only, never for paragraphs.
When is word-break: break-all actually the right choice?
Almost exclusively for non-prose content where a break can happen anywhere without harming meaning: long URLs in a table cell, hash strings, API keys, file names - contexts where mid-word breaks are expected and overflow is worse. For human language text, overflow-wrap: break-word is the correct tool: it breaks only when a word cannot fit on a line by itself, preserving normal reading. CJK content is the exception that proves the rule - Chinese and Japanese break between characters naturally, which is why break-all FEELS normal there and jarring in English.