CSS text decorations are the lines you can draw on text: underlines, overlines, and strikethroughs. They’re great for links, “completed” items, emphasis, and even playful styling (hello, wavy underline).

One important note: text decoration does not make text bold. Bold is handled by font-weight. But you can absolutely combine them (and we will).

What is CSS text decoration?

text-decoration is the umbrella shorthand for styling lines drawn on (or near) text. It can control:

  • Which line(s) appear (underline, overline, line-through)
  • How the line looks (solid, dotted, dashed, wavy, double)
  • The line color
  • The line thickness

You can use the shorthand (one property), or the longhands (multiple properties). Both are valid.

.demo .t1 {
  text-decoration: underline;
}
  
.demo .t1 {
  text-decoration: underline wavy;
}
  
.demo .t1 {
  text-decoration: line-through;
}
  
.demo .t1 {
  text-decoration: none;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.demo {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
  border: 3px solid #111;
  border-radius: 14px;
  background: #f7f7f7;
}

.demo p {
  margin: 0;
  font-size: 22px;
  line-height: 1.3;
}

.demo .hint {
  margin-top: 10px;
  font-size: 14px;
  opacity: 0.75;
}
  

Decorate me. I’m emotionally prepared.

Click the different CSS snippets to switch styles.

The text-decoration property (shorthand)

The shorthand can include up to four pieces:

  • text-decoration-line (underline, overline, line-through)
  • text-decoration-style (solid, dotted, dashed, wavy, double)
  • text-decoration-color (any color)
  • text-decoration-thickness (a length like 2px or keywords like from-font)

You can write them in one line, like: text-decoration: underline wavy #e11d48 3px;

.demo .title {
  text-decoration: underline;
}
  
.demo .title {
  text-decoration: underline dashed;
}
  
.demo .title {
  text-decoration: underline wavy #e11d48;
}
  
.demo .title {
  text-decoration: underline wavy #e11d48 4px;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.demo {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
  border: 3px solid #111;
  border-radius: 14px;
  background: #fff;
}

.demo .title {
  margin: 0;
  font-size: 28px;
  letter-spacing: 0.2px;
}

.demo .sub {
  margin: 10px 0 0 0;
  font-size: 14px;
  opacity: 0.75;
}
  

Text decoration shorthand

Try the snippets: line → style → color → thickness.

CSS text decoration options

Let’s break the “options” into the longhand properties you can mix and match:

  • Line: text-decoration-line
  • Style: text-decoration-style
  • Color: text-decoration-color
  • Thickness: text-decoration-thickness
  • Underline offset: text-underline-offset

The shorthand is convenient, but longhands are often clearer when you’re teaching (or debugging).

text-decoration-line options

This decides which line(s) show up:

  • underline
  • overline
  • line-through
  • none

You can even combine lines, like underline overline.

text-decoration-line:
.demo .text {
  text-decoration-line: underline;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.demo {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
  border: 3px solid #111;
  border-radius: 14px;
  background: #f7f7ff;
}

.demo .text {
  margin: 0;
  font-size: 28px;
  line-height: 1.2;
}

.demo .meta {
  margin: 10px 0 0 0;
  font-size: 14px;
  opacity: 0.75;
}
  

Pick a decoration line

Radio buttons change only text-decoration-line.

CSS text decoration underline

underline is the most common decoration line because it’s used for links, emphasis, and “this is important” vibes. But default browser underlines can be a little… unstyled.

The good news: you can tune underlines with color, thickness, offset, and style.

Underline color with text-decoration-color

You can color the line independently from the text. This is great when you want readable text but a more “designy” underline.

.demo a {
  text-decoration: underline;
  text-decoration-color: #e11d48;
}
  
.demo a {
  text-decoration: underline;
  text-decoration-color: #2563eb;
}
  
.demo a {
  text-decoration: underline;
  text-decoration-color: #16a34a;
}
  
.demo a {
  text-decoration: underline;
  text-decoration-color: currentColor;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.demo {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
  border: 3px solid #111;
  border-radius: 14px;
  background: #fff;
}

.demo p {
  margin: 0;
  font-size: 18px;
  line-height: 1.4;
}

.demo a {
  color: #111;
  font-weight: 600;
}
  

  

Underline offset with text-underline-offset

text-underline-offset moves the underline farther away from the text. This is especially useful for fonts with descenders (like “g”, “y”, “p”) where the underline can feel cramped.

Underline thickness with text-decoration-thickness

text-decoration-thickness lets you control how thick the line is. A slightly thicker underline often looks more intentional (and less “default link”).

.demo .headline {
  text-decoration-thickness: 3px;
  text-underline-offset: 6px;
  text-decoration-line: underline;
  text-decoration-color: #7c3aed;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.demo {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
  border: 3px solid #111;
  border-radius: 14px;
  background: #f8fafc;
}

.demo .headline {
  margin: 0;
  font-size: 34px;
  line-height: 1.15;
}

.demo .note {
  margin: 10px 0 0 0;
  font-size: 14px;
  opacity: 0.75;
  max-width: 58ch;
}
  

Underline tuning playground

Use the sliders to adjust thickness and offset. Notice how the underline “breathes” when you add space.

Underline style with text-decoration-style

The style controls the “stroke pattern” of the decoration line. Common values:

  • solid
  • dotted
  • dashed
  • double
  • wavy
.demo .word {
  text-decoration-line: underline;
  text-decoration-style: solid;
  text-decoration-color: #0f172a;
}
  
.demo .word {
  text-decoration-line: underline;
  text-decoration-style: dotted;
  text-decoration-color: #0f172a;
}
  
.demo .word {
  text-decoration-line: underline;
  text-decoration-style: dashed;
  text-decoration-color: #0f172a;
}
  
.demo .word {
  text-decoration-line: underline;
  text-decoration-style: double;
  text-decoration-color: #0f172a;
}
  
.demo .word {
  text-decoration-line: underline;
  text-decoration-style: wavy;
  text-decoration-color: #e11d48;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.demo {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
  border: 3px solid #111;
  border-radius: 14px;
  background: #fff;
}

.demo .word {
  display: inline-block;
  font-size: 36px;
  font-weight: 700;
  letter-spacing: 0.2px;
}

.demo .tip {
  margin: 12px 0 0 0;
  font-size: 14px;
  opacity: 0.75;
}
  
Underline styles

Try solid, dotted, dashed, double, wavy.

CSS text decoration none

text-decoration: none; removes all decoration lines. The most common use is removing link underlines… but do it carefully.

If you remove a link underline, you should replace it with another clear affordance: a hover underline, a color change, a background highlight, or something that says “I’m clickable”.

.demo a {
  text-decoration: underline;
}
  
.demo a {
  text-decoration: none;
}

.demo a:hover {
text-decoration: underline;
} 
.demo a {
  text-decoration: none;
  border-bottom: 2px solid currentColor;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.demo {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
  border: 3px solid #111;
  border-radius: 14px;
  background: #f7f7f7;
}

.demo p {
  margin: 0;
  font-size: 18px;
  line-height: 1.5;
}

.demo a {
  color: #111;
  font-weight: 700;
}

.demo .small {
  margin-top: 10px;
  font-size: 14px;
  opacity: 0.75;
}
  

This is a link that should look clickable.

Try the snippets: default underline, remove-then-hover, and a border-bottom alternative.

Learn more about link styling in the CSS Link Interactive Tutorial.

CSS text decoration line-through

line-through draws a line through the text (strikethrough). This is perfect for “completed tasks”, “old prices”, or “nope, not that”.

Like underline, you can style it with color, thickness, and style.

.todo .done {
  text-decoration: line-through;
}
  
.todo .done {
  text-decoration: line-through;
  text-decoration-color: #ef4444;
}
  
.todo .done {
  text-decoration: line-through wavy;
  text-decoration-color: #ef4444;
}
  
.todo .done {
  text-decoration: line-through;
  text-decoration-thickness: 4px;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.todo {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
  border: 3px solid #111;
  border-radius: 14px;
  background: #fff;
}

.todo ul {
  margin: 0;
  padding-left: 18px;
  font-size: 18px;
  line-height: 1.6;
}

.todo .done {
  font-weight: 700;
}

.todo .hint {
  margin-top: 10px;
  font-size: 14px;
  opacity: 0.75;
}
  
  • Buy snacks for debugging
  • Ship the feature
  • Remember what “shipped” means

Try different line-through styles, colors, and thickness.

CSS “text decoration bold” (what you actually want)

This one is super common in searches, so let’s say it clearly:

  • Bold text is controlled by font-weight.
  • Decoration lines are controlled by text-decoration.

But you can combine them to create a strong “highlighted link” or “important phrase” style.

.demo .emphasis {
  font-weight: 800;
  text-decoration: underline;
}
  
.demo .emphasis {
  font-weight: 800;
  text-decoration: underline;
  text-decoration-thickness: 4px;
  text-underline-offset: 6px;
}
  
.demo .emphasis {
  font-weight: 800;
  text-decoration: underline wavy;
  text-decoration-color: #f97316;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.demo {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
  border: 3px solid #111;
  border-radius: 14px;
  background: #f8fafc;
}

.demo p {
  margin: 0;
  font-size: 20px;
  line-height: 1.5;
}

.demo .emphasis {
  color: #111;
}
  

Use font-weight for bold, and text-decoration for the line. Together they look intentional.

Learn more about bold text in the CSS Bold Text Interactive Tutorial.

Practical patterns and tips

  • Increase thickness slightly for “designed” links.
  • Add a small underline offset so it doesn’t hug the text.
  • Consider using text-decoration-color to match your brand accent.
.demo a {
  text-decoration-line: underline;
  text-decoration-thickness: 3px;
  text-underline-offset: 5px;
  text-decoration-color: #2563eb;
}
  
.demo a {
  text-decoration-line: underline;
  text-decoration-style: dotted;
  text-decoration-thickness: 3px;
  text-underline-offset: 6px;
  text-decoration-color: #2563eb;
}
  
.demo a {
  text-decoration: none;
}

.demo a:hover {
text-decoration-line: underline;
text-decoration-thickness: 3px;
text-underline-offset: 6px;
text-decoration-color: #2563eb;
} 
*,
::before,
::after {
  box-sizing: border-box;
}

.demo {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
  border: 3px solid #111;
  border-radius: 14px;
  background: #fff;
}

.demo p {
  margin: 0;
  font-size: 18px;
  line-height: 1.55;
}

.demo a {
  color: #111;
  font-weight: 700;
}
  

Modern underline link that still reads like a link.

Extra: text-decoration-skip-ink (underline around letters)

Underlines sometimes collide with letters that drop below the baseline (like “g”, “y”, “p”). Many browsers try to avoid that automatically (“skip ink” behavior).

You can influence this using text-decoration-skip-ink (commonly auto or none). If you turn it off, the underline will draw straight through descenders (sometimes that’s the look you want).

.demo .u {
  text-decoration: underline;
  text-decoration-thickness: 3px;
  text-underline-offset: 3px;
  text-decoration-skip-ink: auto;
}
  
.demo .u {
  text-decoration: underline;
  text-decoration-thickness: 3px;
  text-underline-offset: 3px;
  text-decoration-skip-ink: none;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.demo {
  font-family: ui-sans-serif, system-ui, sans-serif;
  padding: 18px;
  border: 3px solid #111;
  border-radius: 14px;
  background: #f7f7f7;
}

.demo .u {
  margin: 0;
  font-size: 34px;
  font-weight: 700;
}

.demo .note {
  margin: 10px 0 0 0;
  font-size: 14px;
  opacity: 0.75;
}
  

gypy pygmy typography

Compare skip-ink: auto vs skip-ink: none.

Common “text-decoration not working” checklist

  • You’re styling the wrong element. If you want to decorate a link, target the <a>, not just its parent.
  • Another rule is overriding yours. Check the cascade and specificity (browser devtools are your best friend).
  • You removed it earlier. A sneaky text-decoration: none; higher up can quietly win.
  • You expected “bold” from text-decoration. That’s font-weight (but you can combine both).
  • You’re using longhands plus shorthand. Remember: text-decoration (shorthand) can reset related longhands. If something behaves oddly, try using only longhands or only shorthand in that block.

Wrap-up

If you remember only three things:

  1. text-decoration is the shorthand for line, style, color, thickness.
  2. Underlines become “designer underlines” with text-decoration-thickness and text-underline-offset.
  3. “Text decoration bold” is actually font-weight, but the combo looks great.

Next time you see a default underline, you’ll know exactly how to tame it.