v150 · developer trial · css · typography
CSS4 text-decoration-skip-spaces
A new CSS property that controls whether text-decoration lines (underline, overline, line-through) draw under whitespace characters or hop over them. Lets authors get tight, typographically-correct decorations without resorting to splitting text at spaces.
concepts
-
Decoration Toggle
Toggle between
all,none,start,end, andstart endon a paragraph of multi-word linked text. See exactly which spaces the decoration line skips..stage[data-skip="all"] u { text-decoration-skip-spaces: all; } .stage[data-skip="none"] u { text-decoration-skip-spaces: none; } .stage[data-skip="start"] u { text-decoration-skip-spaces: start; } .stage[data-skip="end"] u { text-decoration-skip-spaces: end; } .stage[data-skip="both"] u { text-decoration-skip-spaces: start end; } -
Wrapped Inline
The motivating case from CSSWG issue 3393: two adjacent underlined links wrap to two lines. Compare
none,all,start, andendside by side and watch how the joining underline disappears..underline-none { text-decoration-skip-spaces: none; } .underline-all { text-decoration-skip-spaces: all; } .underline-start { text-decoration-skip-spaces: start; } .underline-end { text-decoration-skip-spaces: end; } -
Prose Links
Multi-word inline links in realistic article body text — the primary use case for
text-decoration-skip-spaces. Switch betweennone,all,start, andendand see how spaces inside link text are handled. A zoomed comparison shows the difference at large scale..article-stage[data-skip="none"] a { text-decoration-skip-spaces: none; } .article-stage[data-skip="all"] a { text-decoration-skip-spaces: all; } .article-stage[data-skip="start"] a { text-decoration-skip-spaces: start; } .article-stage[data-skip="end"] a { text-decoration-skip-spaces: end; } -
Multiline Link Test
Long multi-word links that wrap across lines — the canonical motivating case. Resize the container, select a skip-spaces value and decoration type, and see exactly which spaces on which line get the decoration. A static comparison grid shows all five values side by side.
a.demo-link { text-decoration-line: underline; text-decoration-color: var(--accent-blue); text-decoration-skip-spaces: all; } -
Inline Element Mix
Short links, long links, and highlighted spans in one paragraph — each with its own decoration source. Configure
text-decoration-skip-spacesindependently on each element type and observe that skip-spaces follows the decoration origin, not the final rendered text.a.short { text-decoration-skip-spaces: none; } a.long { text-decoration-skip-spaces: all; } span.hl { text-decoration-skip-spaces: start end; } -
RTL & Vertical Text
startandendare logical keywords — in LTR textstartis the left edge, in RTL (Arabic/Hebrew) it is the right, and in vertical writing modes it is the top. Three panels compare the same value across LTR, RTL, and vertical text simultaneously so the direction-awareness of skip-spaces is obvious..ltr-link { text-decoration-skip-spaces: start; } .rtl-para { direction: rtl; } .rtl-link { text-decoration-skip-spaces: start; } .vert-para { writing-mode: vertical-rl; } .vert-link { text-decoration-skip-spaces: end; }
why it shipped
Underlines under whitespace look off to most readers: the line breaks visual rhythm and confuses kerning. Typography sites have long wanted "underline the words, not the spaces between them". text-decoration-skip-spaces: all is exactly that. The full property surface (with start, end, and combinations) gives finer control for the cases where authors want to mark word boundaries explicitly.
references
implementation reference
Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗