The text-decoration: underline
CSS property provides insufficient control over the underline styling and position. While we wait for the CSS Text Decoration Module specification to become standard, we must rely on custom implementations.
My favorite approach is to use a linear-gradient
to create an underline:
background-image: linear-gradient(gray, gray);
background-size: 100% 1px;
background-position: left bottom;
background-repeat: no-repeat;
Position
Position the underline by changing the vertical value of background-position
:
background-position: left 1.05em;
Descenders
You'll notice that the underline overlaps the descenders of the text. By adding a text-shadow
with a small offset to the right and left with the color of the background, you can hide the underline around descenders.
text-shadow: 0.1em 0 var(--background), -0.1em 0 var(--background);
Remember to set text-shadow: none
in your ::selection
rules.
Weight
Change the height of the background to increase the underline weight:
background-size: 100% 0.25em;
Dashes
By using a repeating-linear-gradient
and leaving half the gradient transparent, you can customize a dashed underline:
background-image: repeating-linear-gradient(
to right,
var(--gray) 0%,
var(--gray) 50%,
transparent 50%,
transparent 100%
);
background-size: 1ch 1px;
Change the horizontal value of background-size
to modify the dash width:
background-size: 5ch 1px;
The ch
unit is equal to the width of the "0" glyph in the current font, which can be useful for natural alignment.
Wrapping
Lastly, this approach also supports multi-line text:
what you do is what you become.
Let me know if you end up using this, or read more about other approaches in "Crafting link underlines on Medium."
Thanks to Franco for reminding me about this technique!