Home / Snippets / Animation & Motion /
Underline slide in
A pseudo-element underline that scales in from the left on hover.
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.