CSS Text Control, Transform, and Overflow
Text control properties determine how text wraps, transforms, breaks, and overflows — critical for building responsive layouts where text content is unpredictable.
1. text-transform
Changes the capitalization of text without modifying the actual HTML:
.uppercase { text-transform: uppercase; } /* ALL CAPS */
.lowercase { text-transform: lowercase; } /* all lowercase */
.capitalize { text-transform: capitalize; } /* First Letter Of Each Word */
.normal-case { text-transform: none; } /* As written in HTML */
Common uses:
/* Navigation labels */
.nav__item { text-transform: uppercase; letter-spacing: 0.1em; font-size: 0.8rem; }
/* Badge / tag */
.tag { text-transform: uppercase; font-size: 0.7rem; letter-spacing: 0.15em; font-weight: 700; }
/* Button — capitalize all for consistency regardless of HTML casing */
.btn { text-transform: uppercase; }
2. text-decoration
Controls underlines, overlines, and strikethroughs:
a { text-decoration: none; } /* Remove default link underline */
.strikethrough { text-decoration: line-through; } /* Strikethrough — for sale prices */
.overline { text-decoration: overline; }
/* Shorthand: text-decoration: line style color thickness */
a:hover {
text-decoration: underline;
text-decoration-color: var(--color-primary);
text-decoration-thickness: 2px;
text-underline-offset: 4px; /* Gap between text and underline */
}
Stylish underline effect:
.fancy-link {
text-decoration: none;
background-image: linear-gradient(var(--color-primary), var(--color-primary));
background-size: 0 2px;
background-position: 0 100%;
background-repeat: no-repeat;
transition: background-size 0.3s ease;
}
.fancy-link:hover { background-size: 100% 2px; }
3. text-align
.left { text-align: left; } /* Default for LTR languages */
.center { text-align: center; }
.right { text-align: right; }
.justify { text-align: justify; } /* Stretches text to fill width — use carefully */
/* Modern logical properties */
.start { text-align: start; } /* Left in LTR, Right in RTL */
.end { text-align: end; }
4. white-space — Line Wrapping Control
Controls how white space and line breaks inside an element are handled:
| Value | Whitespace | Wrapping | \n in HTML |
|---|---|---|---|
normal (default) | Collapsed | Wraps | Ignored |
nowrap | Collapsed | Does NOT wrap | Ignored |
pre | Preserved | Does NOT wrap | Respected |
pre-wrap | Preserved | Wraps | Respected |
pre-line | Collapsed | Wraps | Respected |
break-spaces | Preserved | Wraps at spaces | Respected |
/* Common uses */
.no-wrap { white-space: nowrap; } /* Prevents line breaks — used in truncation */
.code-block { white-space: pre; } /* Preserves indentation in code */
.pre-wrap { white-space: pre-wrap; } /* Preserves but wraps — chat messages */
5. Text Overflow — Truncation Patterns
Single Line Truncation (Ellipsis)
The most common truncation pattern — requires 3 properties together:
.truncate {
white-space: nowrap; /* 1. Prevent wrapping */
overflow: hidden; /* 2. Clip the overflow */
text-overflow: ellipsis; /* 3. Show '...' at cutoff */
}
/* Practical: card title truncation */
.card__title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 300px;
}
Multi-Line Truncation (-webkit-line-clamp)
Limits text to N lines, adding ... at the end:
/* 2-line clamp */
.excerpt {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
/* 3-line clamp */
.description {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
/* Modern native: line-clamp (still needs -webkit- prefix for now) */
.clamp-4 { overflow: hidden; display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; }
6. word-break and overflow-wrap
Controls how long words and URLs break across lines:
/* word-break */
.normal { word-break: normal; } /* Default — break only at valid points */
.break-all { word-break: break-all; } /* Break at ANY character (even mid-word) */
.keep-all { word-break: keep-all; } /* No mid-word breaks (CJK languages) */
.break-word { word-break: break-word; } /* Break long words only if nec. (deprecated) */
/* overflow-wrap (preferred over word-break for this use case) */
.wrap-long { overflow-wrap: break-word; } /* Break long URLs/strings if they overflow */
.wrap-normal { overflow-wrap: normal; } /* Default */
.wrap-any { overflow-wrap: anywhere; } /* Like break-word, affects min-content size */
Best practice for prose content:
p, li, td {
overflow-wrap: break-word; /* Prevent URL/code strings from breaking layout */
word-break: normal;
}
7. hyphens
Automatically hyphenate words at syllable breaks when wrapping:
.hyphenated {
hyphens: auto;
-webkit-hyphens: auto;
lang: en; /* Must set lang attribute on HTML element for auto hyphens */
}
/* <html lang="en"> is required */
.no-hyphens { hyphens: none; } /* No auto hyphenation */
.manual { hyphens: manual; } /* Only break at ­ soft hyphens */
8. text-indent
Indents the first line of a text block:
.article p { text-indent: 1.5em; } /* Classic book typography */
.hanging { text-indent: -1em; padding-left: 1em; } /* Hanging indent for lists */
9. Letter and Word Spacing
.tight { letter-spacing: -0.03em; } /* Tight — large headings */
.normal { letter-spacing: 0; }
.tracked { letter-spacing: 0.08em; } /* Tracked — uppercase labels */
.spaced { letter-spacing: 0.15em; } /* Wide — decorative */
.compact { word-spacing: -0.05em; } /* Compress words */
.airy { word-spacing: 0.15em; } /* Loosen words */
10. text-shadow
/* Subtle legibility shadow on image text */
.hero-title { text-shadow: 0 2px 20px rgba(0,0,0,0.5); }
/* Glow effect */
.neon { text-shadow: 0 0 10px var(--color-primary), 0 0 30px var(--color-primary); }
/* Embossed text */
.emboss { text-shadow: 1px 1px 0 rgba(255,255,255,0.3), -1px -1px 0 rgba(0,0,0,0.3); }
11. writing-mode — Vertical Text
.vertical-lr { writing-mode: vertical-lr; } /* Asian top-to-bottom, left-to-right */
.vertical-rl { writing-mode: vertical-rl; } /* Japanese writing direction */
.sideways { writing-mode: sideways-lr; } /* Western text rotated 90° */
/* Vertical sidebar label */
.sidebar-label {
writing-mode: vertical-rl;
transform: rotate(180deg); /* Flip to read bottom-up */
text-transform: uppercase;
letter-spacing: 0.15em;
}