Home / Snippets / Animation & Motion /

Underline slide in

A pseudo-element underline that scales in from the left on hover.

Widely Supported
animationno-js

Quick implementation

.underline-slide {
  position: relative;
  text-decoration: none;
}

.underline-slide::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -2px;
  width: 100%;
  height: 2px;
  background: oklch(0.72 0.19 265);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s ease;
}

.underline-slide:hover::after {
  transform: scaleX(1);
}

@media (prefers-reduced-motion: reduce) {
  .underline-slide::after { transition: none; }
}

Prompt this to your LLM

Includes role, constraints, two framework variants, and edge cases to handle.

You are a senior frontend engineer building navigation hover effects.

Goal: An animated underline that slides in from the left on hover using a ::after pseudo-element — no JavaScript.

Technical constraints:
- Use ::after with position: absolute, bottom: -2px, width: 100%, height: 2px.
- Animate with transform: scaleX(0) → scaleX(1) for GPU-composited performance.
- Set transform-origin: left for left-to-right reveal.
- Use oklch() for the underline color, not hex or rgba().
- Transition: 0.3s ease for a smooth slide.
- Include @media (prefers-reduced-motion: reduce) to disable the transition.

Framework variant (pick one):
A) Vanilla CSS class applicable to any link or text element.
B) React component — accept color, thickness, and direction props.

Edge cases to handle:
- Parent must have position: relative for the pseudo-element to anchor correctly.
- Works on multi-word links — the underline spans the full text width.
- For right-to-left slide, change transform-origin to right.
- For center-out, use transform-origin: center.

Return CSS.

Why this matters in 2026

The sliding underline replaces the default text-decoration: underline with a polished, animated alternative. It's the standard hover pattern for navigation links, content links, and tab labels. One pseudo-element and a scaleX transform — no images, no JavaScript.

The logic

The ::after pseudo-element sits below the text with width: 100% but scaleX(0), making it invisible. On hover, scaleX(1) reveals it. transform-origin: left controls the direction — the underline grows from left to right. Using scaleX instead of width keeps the animation on the GPU compositor.

Accessibility & performance

The underline provides visual hover feedback that complements :focus-visible styles. prefers-reduced-motion disables the slide so the underline appears instantly. transform: scaleX() is compositor-only — no layout or paint cost. Ensure the link's color alone provides sufficient contrast even without the underline.