Rainbow Button
A button with a flowing rainbow gradient animation, in solid and outline styles, with a soft glow in matching hues.
A button whose rainbow gradient keeps flowing horizontally, with solid and outline styles built in plus an adjustable flow speed and a matching-hue glow.
Bring this into your project
Run this command in your project folder. The CLI adds the source and dependencies; then follow the usage example below.
npx webberui@latest add rainbow-button.enRainbow Button is a React rainbow gradient button built with Tailwind CSS and CSS keyframes: the gradient flows continuously through a background-position animation, a blurred glow in the same colors sits underneath, and an outline variant shows the rainbow only on the border. Motion is used only to read the reduced-motion setting.
Playground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<RainbowButton/>
The complete example includes the preview layout and data. Install the component first, then paste this file into your project.
When to use
- The primary call to action in a landing page hero, such as "Start free trial" or "Get started"
- An entry point that has to stand out on a feature launch or event page
- Secondary buttons on dark developer-tool pages, using the
outlinevariant - Once per screen, so it doesn't compete with other buttons
Installation
npx webberui@latest add https://webberui.com/r/rainbow-button.en.jsonOr, once registries are configured in components.json, install it as @webberui/rainbow-button.
Usage
import { RainbowButton } from "@/components/ui/rainbow-button";
<RainbowButton>Get Started</RainbowButton>
<RainbowButton variant="outline">Outline</RainbowButton>Custom color ramp and flow speed:
<RainbowButton
colors={["#ff4d4d", "#4dd2ff", "#c14dff"]}
speed={1.5}
>
Custom
</RainbowButton>RainbowButton forwards all native <button> attributes (onClick, disabled, type, and so on).
Examples
With an icon
The children wrapper is already inline-flex with gap-2, so drop in text and an icon.
import { ArrowRight } from "lucide-react";
import { RainbowButton } from "@/components/ui/rainbow-button";
<RainbowButton className="px-6 py-3 text-base">
Start free trial
<ArrowRight className="size-4" />
</RainbowButton>Form submit with a pending state
Native button attributes are passed through, so type="submit" and disabled work as usual; a disabled button gets opacity-50 and ignores pointer events.
"use client";
import { useFormStatus } from "react-dom";
import { RainbowButton } from "@/components/ui/rainbow-button";
export function SubmitButton() {
const { pending } = useFormStatus();
return (
<RainbowButton type="submit" disabled={pending}>
{pending ? "Submitting…" : "Join the waitlist"}
</RainbowButton>
);
}Dark brand palette
The solid variant uses near-black text by default; with a dark palette, switch to white text through className. glow={false} removes the glow underneath.
<RainbowButton
colors={["#1e3a8a", "#7c3aed", "#be185d"]}
speed={5}
glow={false}
className="text-white"
>
Book a demo
</RainbowButton>Props
| Prop | Type | Default | Description |
|---|---|---|---|
colors | string[] | the seven rainbow colors | The rainbow color ramp; the end loops back to the first color to close the ring, minimum two colors |
speed | number | 3 | Duration of one flow cycle (seconds); smaller is faster |
variant | "solid" | "outline" | "solid" | solid fills with the gradient; outline shows the rainbow only on the border and the glow |
glow | boolean | true | Whether to layer a soft glow in matching hues underneath |
className | string | — | Styles forwarded to the root button |
All native button attributes are supported as well.
Accessibility
- When the user has "reduce motion" enabled at the system level, the gradient flow pauses at a standstill while the rainbow appearance is kept
- On focus it provides a clear
focus-visibleoutline ring, keeping keyboard operation visible - Rendering is identical before and after mounting, avoiding an SSR hydration mismatch
FAQ
Can I use it as a link?
It always renders a <button> and has no asChild option. For navigation, call your router in onClick (for example router.push in Next.js) rather than wrapping it in an <a>, since a button inside a link is invalid HTML nesting.
Does it work with the Next.js App Router?
Yes. The source already has "use client", so import it from a Server Component page. The animation keyframes are injected into <head> after mount, and all buttons share a single copy.
How do I change the speed and colors?
speed is the length of one cycle in seconds, so lower is faster. colors takes any CSS color strings, at least two, and the first color is appended to the end so the loop has no seam.
What happens with reduced motion enabled?
The gradient pauses in place; the button keeps its rainbow look without moving.
What are the dependencies?
motion, clsx, tailwind-merge, and the cn helper in @/lib/utils; lucide-react is only needed for the icon in the example. You can also copy the source from the Manual tab.