← All effects

Elastic Tabs

Micro-interactionVanilla JS · zero dependenciesTwo springs, one div
-- fps
prefers-reduced-motion detected — indicator jumps without stretching

X-ray · layers

the indicator travels (off = jumps)
front edge leads, back edge lags
springy overshoot on arrival

Parameters

Speed14
Lag ratio0.45
Bounciness0.72
Auto demo every1800 ms
your version · updates as you tinker

How this effect works

The gum illusion comes from tracking the indicator's two edges separately. The front edge (the one facing the target tab) runs on a fast spring; the back edge runs on a slow one, scaled by the lag ratio. While travelling, the edges pull apart — the indicator visibly stretches — and as the front arrives and waits for the back to catch up, it snaps back together. Nobody animates "width": the width is just front − back, recomputed every frame.

Each edge is a proper spring, not an easing curve: velocity accumulates toward the target and gets damped by the bounciness factor. Lower damping lets the edges fly past the target and wobble in — that's the wobble layer. Because springs respond to wherever the indicator currently is, clicking tabs rapidly mid-flight looks natural for free: the indicator just changes course, stretch and all.

Production notes: respects prefers-reduced-motion (indicator jumps instantly) · one absolutely-positioned div, animated with transform + width · works with any number of tabs — edges are measured from the DOM · the copied snippet is self-contained HTML + CSS + JS.