WebCraft

background-size

An underline that slides in

Caveattext-decoration cannot animate its width, so the underline here is a background: a one-colour gradient sized 0% 2px, grown to 100%. The catch is that the percentage resolves against the whole inline box — on a link that wraps, each line fragment shows a slice of one long underline. Keep it for single-line labels and give wrapped prose links a plain text-decoration.

FallbackGive :focus-visible the same treatment — keyboard users hover nothing. With animations off the size still lands, instantly, so nothing is lost but the slide.

CSS
a {
  /* the underline is a background */
  background:
    linear-gradient(currentColor, currentColor)
    no-repeat left 100% / 0% 2px;
  transition: background-size .25s;
}

a:hover,
a:focus-visible { background-size: 100% 2px; }

Published

Questions

<details name>

Why animate a background instead of text-decoration?

Because text-decoration cannot animate its width. A one-colour gradient sized 0% 2px and grown to 100% can, and unlike a pseudo-element it follows the text rather than the box.

Why does the underline look wrong on a link that wraps?

The percentage resolves against the whole inline box, so each line fragment shows a slice of one long underline rather than its own. Keep this for single-line labels and give wrapped prose links a plain text-decoration.

Does this work for keyboard users?

Only if you give :focus-visible the same rule as :hover — keyboard users hover nothing. With animations turned off the size still lands, instantly, so nothing is lost but the slide.