The CSS Text Decoration Module Level 3 gives us several ways to style text decoration beyond the basic underline / line-through toggle. Browser support today sits above 94% globally, so these properties are safe to use in production.
Properties like text-decoration-thickness and text-decoration-color let you control underline weight and color independently – things that required workarounds before. If you’re still getting comfortable with CSS fundamentals, check the complete CSS guide for beginners first.
A common need I ran into for years: changing the underline color without changing the text color. Another one: matching the underline thickness to a specific design comp.
Before these properties landed, the go-to hack was
border-bottompaired withpadding-bottom. It worked, but it wasn’t a real underline and broke on multi-line text.
The text-decoration Property
Originally, text-decoration only accepted none, underline, overline, or line-through.
With the Level 3 spec it became a shorthand that combines text-decoration-line, text-decoration-style, and text-decoration-color in a single declaration. Here’s a double underline in hot pink:
The CSS:
text-decoration: #ff00d3 double underline;Older versions of Safari ignored the shorthand when
text-decoration-stylewas included. The workaround is to add-webkit-text-decorationright after the standard property, or write each sub-property on its own line.
The complete set of text-decoration sub-properties available today:
- text-decoration-thickness
- text-decoration-color
- text-decoration-line
- text-decoration-style
- text-decoration-skip
- text-decoration-skip-ink
- text-decoration
- text-underline-offset
- text-underline-position
4 Examples of Decoration and Underline Properties
Let’s walk through each property with a live demo. All modern browsers support these properties (94%+ global coverage):
A. text-decoration-thickness
text-decoration-thickness controls how thick the line is. You can use any length value – px, em, or even from-font to let the font metrics decide:
B. text-decoration-color
text-decoration-color sets the underline color independently from the text color. Any valid CSS color works – hex, rgb(), hsl(), or named colors:
C. text-underline-offset
text-underline-offset moves the underline up or down relative to its default position. Positive values push it away from the text, negative values bring it closer:
D. text-decoration-skip-ink
Look closely at the previous examples – the underline breaks around the descenders of certain glyphs (the parts that drop below the baseline, like in the letters g, p, q, y, j).
That gap is the default behavior. The browser sets text-decoration-skip-ink to auto, which tells it to skip ink where the line would collide with a glyph. Setting the value to none draws the underline straight through every letter:
In typography, the part of a letter that extends below the baseline is called a descender (g, p, q, y, j). The part that rises above the x-height is an ascender (b, d, h, k, l).
Here’s a video by Jen Simmons (now at Apple, previously at Mozilla) that covers these properties in detail:
FAQs
text-decoration-color. For example, text-decoration-color: #ff00d3; sets a pink underline while the text stays whatever color you defined with color. Before this property existed, the only option was faking an underline with border-bottom.text-decoration-thickness controls the actual text underline rendered by the browser. It wraps correctly on multi-line text and respects text-decoration-skip-ink. border-bottom is a box-model border that sits below the element's padding - it doesn't follow individual text lines and can't skip descenders.text-decoration-skip-ink controls whether the underline breaks around glyph descenders and ascenders. The default value is auto, which lets the browser skip ink where the line would collide with letters like g, p, or y. Setting it to none draws the underline straight through every letter. The value all forces skipping even in scripts (like CJK) where auto might not skip.text-decoration-color, text-decoration-thickness, and text-underline-offset are all animatable. You can add transition: text-decoration-color 0.3s, text-underline-offset 0.3s; and change the values on :hover for smooth underline effects.text-decoration shorthand only sets text-decoration-line, text-decoration-style, and text-decoration-color. Properties like text-decoration-thickness, text-underline-offset, and text-decoration-skip-ink must be declared separately.from-font value tells the browser to use the thickness value stored in the font file itself, if available. If the font doesn't include that metric, the browser falls back to auto. This is useful when you want the underline to match the weight the type designer intended.Summary
The CSS Text Decoration Level 3 properties give you real control over underline styling – thickness, color, offset, and ink-skipping behavior – without the old border-bottom hacks. I find them especially useful for editorial layouts and link styling where a subtle text-underline-offset paired with a lighter text-decoration-color makes links feel polished without extra markup.
For another text styling technique worth exploring, see my post on CSS text-shadow effects.


This is a great article about how to change the text-decoration in modern CSS. It’s a good change to go from border-bottom hacks to native text-decoration-thickness and text-underline-offset. The note about Safari compatibility for the shorthand syntax is especially helpful because that bug can be hard to find if you don’t know what to look for.
I have noticed a big difference in how easy it is to read text when I use text-decoration-skip-ink, especially with fonts that have big descenders. In addition to underline styling, I’ve been looking into other text effects, such as glitch and decorative Unicode transformations.
Tools like GlitchText.cool are useful for quickly seeing how stylized text works with different layouts and decorations. Throughout, a clear explanation.