Shimmer button
Free · MITA light sweep runs across the button. Pure CSS; the sweep is removed for reduced motion.
Installation
$ npx shadcn@latest add https://goodui.dev/r/shimmer-button.jsonThe file lands in components/goodui/shimmer-button.tsx and is yours to edit. With the @goodui registry added, npx shadcn@latest add @goodui/shimmer-button works too.
Usage
import { Sparkles } from "lucide-react"
import { ShimmerButton } from "@/components/goodui/shimmer-button"
export function UpgradeCta({ onUpgrade }: { onUpgrade: () => void }) {
return (
<ShimmerButton onClick={onUpgrade}>
<Sparkles />
Upgrade to Pro
</ShimmerButton>
)
}When to use
- One call to action that should catch the eye on a landing or pricing page ("Start free trial").
- An upgrade prompt inside an app, where a slow sweep hints at the action without a badge.
- When you want a single standalone file with no variants to learn: one primary-colored button with a sweep.
- You already use the Core button: button with animation="shimmer" gives the same sweep plus every variant, tone, size and the loading state. That is the simpler choice in most apps.
- Several buttons on one screen: a looping sweep on each one competes for attention; keep shimmer to the main action and use button for the rest.
- Async actions that need loading, success and error feedback: use stateful-button.
| If you need | Use |
|---|---|
| Calmer, occasional sweep | duration={4} |
| Faster, more energetic sweep | duration={1.6} |
| Band visible on a light or custom background | shimmerColor="rgb(255 255 255 / 0.7)" or a brand color, plus your own className for the face |
| Same sweep with variants, tones and loading | button with animation="shimmer" |
Examples
Large hero button with a slower sweep
<ShimmerButton duration={3.6} className="h-12 rounded-full px-8 text-base">
Book your first cleaning
</ShimmerButton>Custom face and band color
<ShimmerButton
className="bg-emerald-600 text-white hover:bg-emerald-600/90"
shimmerColor="rgb(255 255 255 / 0.6)"
>
Accept quote · $240
</ShimmerButton>API reference
| Prop | Type | Default |
|---|---|---|
| duration Seconds per sweep. | number | 2.4 |
| shimmerColor Color of the light band. | string | — |
Also accepts every <button> attribute.
Accessibility
| Enter / Space | Activates the button (native <button>). |
| Tab | Moves focus; a focus ring shows on keyboard focus only. |
- Renders a native <button> and passes every button attribute through, so type, disabled, form and aria-* work as usual.
- The light band is a ::after pseudo-element with pointer-events: none; it is not announced and never blocks clicks.
- Disabled buttons get 50% opacity and no pointer events.
Motion
- A 45%-wide light band, skewed by -20deg, sweeps from left to right on an ease-in-out loop every `duration` seconds (2.4 s by default).
- Press scales the button to 0.98; hover deepens the shadow.
- Reduced motion: the sweep is removed (animation off, band hidden); the button stays fully usable.
- The sweep is a CSS transform animation on one pseudo-element; no JavaScript runs while it loops.
Notes for AI
Coding agents read these rules through MCP and llms.txt, or paste this page with Copy page.
- Pass content as children (icons go inline before or after the text); there is no variant, size or icon prop.
- Restyle the face with className (bg-*, h-*, rounded-*, px-*); the sweep follows the border radius because the button clips overflow.
- duration is in seconds, not milliseconds.
- Use it for one main action per screen; for full variant control use the Core button with animation="shimmer" instead.
FAQ
What is the difference from the Core button's shimmer animation?
Both sweep a light band. The Core button adds variants, tones, sizes, icons and loading, and sweeps every 2.6 s; ShimmerButton is a single small file with a configurable duration and band color.
The band is hard to see on my button.
The default band is white at 45% opacity, made for a dark or saturated face. On a light face pass a stronger or darker shimmerColor.
Related
One button with ten variants, six tones, seven shadows, ten animations, three shapes and five sizes that all combine, plus loading and icon slots.
A soft light band sweeps across muted text on a loop or on hover, made for badges like "New: AI receptionist". Pure CSS.
A short light beam rides around the button's rounded border with CSS offset-path, with a conic fallback and a static gradient for reduced motion.
Button with a seamlessly flowing rainbow border and a soft colored glow underneath, tuned to invert cleanly between light and dark themes.