NavigationFree

Underline Expand

A 2 px underline grows symmetrically from the center of the link on hover — pure CSS, zero JavaScript.

CSSCenter
Hover or click the scene to interact

This effect is free — the Navigation category contains 36 effects total, including 4 free. Effect.Labs has 811 vanilla effects. Explore the category →

Usage examples

Welcome back
Dashboard
Revenue
24 800 €
+12,4 %
Active users
1 342
+8,1 %
Conversion
3,8 %
+0,4 pt

① Main navigation — SaaS application

WhenThe primary tabs of a web app (Dashboard, Projects, Team, Settings) are aligned in a fixed horizontal navigation bar.
WhyThe symmetric expansion from center is visually balanced regardless of label length — it highlights the active item without crowding neighbors or causing layout shifts.
SettingsTransition at 0.25 s for snappier feedback, --gradient-primary matched to the app's accent color, height 2 px.
Effect Library
Explore all effects
811 effects · filter by category
CSS
Underline Expand
Navigation
CSS
Fade Slide In
Transitions
JS
Confetti Cannon
Atmosphère
Motion
Blob Morph
Arrière-plans
CSS
Shimmer Text
Typographie
JS
Particle Trail
Curseur

② Filter bar — Catalogue or documentation

WhenA row of clickable tags filters a catalogue of articles (All, CSS, JavaScript, Motion, Layout) — the active item shows the underline permanently, others on hover.
WhyThe centered underline works regardless of filter label length and creates an elegant common baseline without taking up extra space.
SettingsHeight 3 px for more visibility, --gradient-primary: #6366f1 (solid color), transition 0.2 s.
Aether
✦ New — Version 2.0 available

Build faster,
ship with confidence

The platform that scales with your team. From prototype to production in minutes.

③ Section anchors — Long-scroll landing page

WhenA fixed semi-transparent navbar overlays a dark hero section with anchor links (How it works, Pricing, FAQ).
WhyOn a dark background, the indigo-violet gradient underline draws attention on hover without being intrusive — ideal for ambient navigation that stays understated while scrolling.
Settings--text-secondary: rgba(255,255,255,0.65), --text-primary: #fff, transition 0.35 s for cinematic smoothness.

How it works

The effect relies on an ::after pseudo-element anchored to the link's center via left: 50% and transform: translateX(-50%). At rest, width: 0 hides it. On hover, width: 100% makes it grow toward both edges simultaneously — this centering is what creates the illusion of expansion from the middle rather than from one side.

The underline background uses var(--gradient-primary), inheriting the gradient defined in the host theme. The 0.3 s CSS transition (transition: 0.3s on ::after) animates the width smoothly, with zero JavaScript and no runtime measurements.

At the same time, the text color shifts from var(--text-secondary) to var(--text-primary) via its own transition: color 0.3s declaration. The two transitions target distinct properties and run without conflict — one animates width on ::after, the other animates color on the parent element.

The effect is fully declarative: no JS, no event listeners. Add the class .link-underline-expand to any <a>, <span>, or <button> with position: relative to activate it immediately.

Accessibility

  • prefers-reduced-motion not present in the code: the 0.3 s transition runs even when the OS signals a preference for reduced motion. Recommended fix: @media (prefers-reduced-motion: reduce) { .link-underline-expand::after { transition: none; } }.
  • The effect is purely decorative: the text color also changes on hover, providing a second state indicator independent of the underline — useful for color-blind users or those who disable pseudo-elements.
  • The demo code uses <span> elements — in production, use native <a> elements and add .link-underline-expand:focus-visible::after { width: 100%; } to activate the effect on keyboard navigation.
  • Contrast depends on the host theme's CSS variables. In the Effect.Labs dark theme, --text-secondary (#a1a1aa on #0a0a0f) reaches a ~4.6:1 ratio, meeting WCAG AA.
  • The effect only adds visual information — no content is hidden or removed from the flow, no impact on screen readers.

Browser compatibility

Requires ::after, CSS transitions and custom properties (var()) — supported in all modern browsers since 2017.

Chrome 49+✓ Full
Firefox 31+✓ Full
Safari 9.1+✓ Full
Edge 15+✓ Full
Mobile iOS✓ Full
Android Chrome✓ Full

Without CSS custom properties (<code>var()</code>), browser default colors apply. Without CSS transitions, the underline appears and disappears instantly — functional but without animation.

The code

Copy the three blocks into your page. No dependencies.

HTML
<div class="nav-demo">
  <span class="nav-link-demo link-underline-expand">Accueil</span>
  <span class="nav-link-demo link-underline-expand">Services</span>
  <span class="nav-link-demo link-underline-expand">Contact</span>
</div>
CSS
.nav-demo  {
   display: flex;
   gap: var(--space-8);
   align-items: center;
   }

.nav-link-demo  {
   color: var(--text-secondary);
   font-weight: 500;
   padding: var(--space-2) 0;
   position: relative;
   cursor: pointer;
   transition: color 0.3s;
   }

.nav-link-demo:hover  {
   color: var(--text-primary);
   }

.link-underline-expand::after  {
   content: "";
   position: absolute;
   bottom: 0px;
   left: 50%;
   width: 0px;
   height: 2px;
   background: var(--gradient-primary);
   transition: 0.3s;
   transform: translateX(-50%);
   }

.link-underline-expand:hover::after  {
   width: 100%;
   }
JavaScript (fx-0449)
// Effet CSS pur — pas de JavaScript nécessaire

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
var(--gradient-primary) indigo→violet→pink gradient Underline color or gradient. Replace with a solid color (#6366f1) or a custom gradient.
height: 2px (in ::after) 2px Line thickness. 1 px = ultra-subtle, 3–4 px = prominent.
bottom: 0px (in ::after) 0px Vertical offset from the baseline. A negative value like -4px moves the line away from the text.
transition: 0.3s (in ::after) 0.3s Expansion animation duration. 0.15 s = snappy, 0.5 s = cinematic.
width: 100% (in :hover::after) 100% Maximum underline width on hover. 80% gives a slightly shorter line, centered below the text.
var(--text-secondary) / var(--text-primary) #a1a1aa / #ffffff Text colors at rest and on hover, defined in the host theme.
var(--space-8) (gap in .nav-demo) 2rem Spacing between navigation links. Reduce to 1rem for a more compact navigation.

FAQ

Can the underline stop at 80% width rather than spanning the full link?

Yes — change .link-underline-expand:hover::after { width: 80%; }. The line stays centered via left: 50% + translateX(-50%), so it will always be centered below the text regardless of the target width.

How do I trigger the effect on keyboard focus, not just mouse hover?

Add .link-underline-expand:focus-visible::after { width: 100%; } to your CSS. This activates the underline during keyboard navigation (Tab) with the same transition, without affecting mouse behavior.

Can I combine a static underline at rest with the expand effect on hover?

Yes — set a non-zero width at rest, for example .link-underline-expand::after { width: 20%; }. On hover it will grow to 100% with the transition, creating a growth effect rather than an appearance from zero.