Skip to content
Menu

Experiment #004

Shimmer Button

A skewed band of light — a functional linear gradient from transparent to white and back — sits clipped inside the button and rides translateX from -150% to 350% when the pointer enters. The sweep is a one-shot CSS animation retriggered on each hover or keyboard focus, animating transform only. No JavaScript, and the band stays parked off-canvas for users who prefer reduced motion.

Scene

Technical details

Experiment
FX-004
Category
Buttons
Stack
Tailwind + CSS
Difficulty
Beginner
Dependencies
none
Weight
HTML 1.2 KB · CSS 1.1 KB
Added
2026-08-23
Updated
2026-08-23

Lab notes

The band width (40%) and skew (-20deg) set the character of the sheen: narrower and steeper reads as glass, wider and flatter reads as satin. Keep the white stop at 0.3–0.4 alpha on dark buttons; anything brighter looks like a glitch. Around 0.8s is the sweet spot — faster feels nervous, slower feels laggy.

Take the code

HTML — code.html
<!-- Shimmer Button — Tailwind CSS -->
<style>
    .shimmer-band {
        background: linear-gradient(
            105deg,
            transparent 0%,
            rgba(255, 255, 255, 0.35) 50%,
            transparent 100%
        );
        transform: translateX(-150%) skewX(-20deg);
    }

    @keyframes shimmer-sweep {
        from {
            transform: translateX(-150%) skewX(-20deg);
        }

        to {
            transform: translateX(350%) skewX(-20deg);
        }
    }

    .shimmer-button:hover .shimmer-band,
    .shimmer-button:focus-visible .shimmer-band {
        animation: shimmer-sweep 0.8s ease;
    }

    @media (prefers-reduced-motion: reduce) {
        .shimmer-button .shimmer-band {
            animation: none !important;
        }
    }
</style>

<button
    type="button"
    class="shimmer-button relative overflow-hidden rounded-full bg-zinc-900 px-7 py-3
           text-sm font-medium text-white focus-visible:outline-2
           focus-visible:outline-offset-4 focus-visible:outline-zinc-500"
>
    <span
        class="shimmer-band pointer-events-none absolute inset-y-0 left-0 w-2/5"
        aria-hidden="true"
    ></span>
    <span class="relative">Hover me</span>
</button>
CSS — styles.css
/* Shimmer Button — vanilla CSS (no Tailwind, no extra markup: the band is a pseudo-element) */

.shimmer-button {
    position: relative;
    overflow: hidden;
    padding: 0.75rem 1.75rem;
    border: 0;
    border-radius: 9999px;
    background: #18181b;
    color: #fff;
    font: 500 0.875rem/1.25rem system-ui, sans-serif;
    cursor: pointer;
}

.shimmer-button:focus-visible {
    outline: 2px solid #71717a;
    outline-offset: 4px;
}

.shimmer-button::before {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 40%;
    background: linear-gradient(
        105deg,
        transparent 0%,
        rgba(255, 255, 255, 0.35) 50%,
        transparent 100%
    );
    transform: translateX(-150%) skewX(-20deg);
    pointer-events: none;
}

@keyframes shimmer-sweep {
    from {
        transform: translateX(-150%) skewX(-20deg);
    }

    to {
        transform: translateX(350%) skewX(-20deg);
    }
}

.shimmer-button:hover::before,
.shimmer-button:focus-visible::before {
    animation: shimmer-sweep 0.8s ease;
}

@media (prefers-reduced-motion: reduce) {
    .shimmer-button::before {
        animation: none;
    }
}

Adjacent

Specimens nearby

All Buttons →
FX-003 Buttons