shadcn.io is not affiliated with official shadcn/ui
A ring of color runs around the button's edge and keeps turning, and a blurred halo of the same colors follows it outside. The label sits on the button's own fill, so it stays as readable as any Button.
Use it for the one action a page is built around: an upgrade, a trial, a launch. Don't put it on every button, or none of them stands out; for a ring that only turns when the pointer reaches it, use the Flow Button. It wraps the Button, so variant and size work as usual. The ring is a conic gradient rotated under a ring-shaped mask by a CSS keyframe animation the install adds to your stylesheet, with no JavaScript and no animation library. With reduced motion the ring and halo stay, standing still.
Installation
Usage
import { GlowBorderButton } from "@/components/ui/glow-border-button";<GlowBorderButton>Upgrade to Pro</GlowBorderButton>Demos
Colors
colors takes any CSS colors, in order around the ring, and the last one blends back into the first. The default is two bright arcs of the primary color on a faint primary ring. Here one ring mixes the primary and destructive colors for a live broadcast, and the other is a single arc of the foreground color that sweeps around an otherwise empty edge.
Intensity
intensity sets the halo: subtle has none, just the ring; medium, the default, a soft one; strong a wider, brighter one. The ring itself stays the same width. On a busy page, or with many buttons on screen, subtle is the lightest to draw and keeps the glow from bleeding into nearby content.
Duration
duration is how long one full turn takes, in milliseconds, and the default is 3000. A fast turn feels urgent; a slow one is easier to live with on a page people stay on. paused stops the turn and keeps the ring and halo drawn, for a state such as Sold out.
Accessibility
The ring and the halo are decoration and hidden from assistive tech: the button is announced and activated as any Button. They're drawn over the button's border, so its focus ring still shows around it on keyboard focus.
- Enter
- Activate the button.
- Space
- Activate the button.
FAQ
How do I change the ring's colors?
Pass colors, an array of CSS colors such as var(--primary) or var(--destructive). They go around the ring in order and the last blends into the first. The Colors demo shows two sets.
How do I make it turn slower or faster?
Set duration, the time for one full turn in milliseconds; the default is 3000. The Duration demo shows 1500 and 8000.
Can I stop the rotation?
Yes. Pass paused and the ring stands still where it is, with its halo. You can switch it on and off, for example while a form is submitting.
The halo is too strong. How do I tone it down?
Pass intensity="subtle" for the ring alone, with no halo. The default is medium, and strong spreads it further.
Will a ring that never stops slow the page down?
No. The colors are drawn once on a layer, and the keyframes only rotate it under the mask, which the browser can hand to the compositor: no repaint, no re-render and no JavaScript while it turns. The halo adds a blur the graphics card applies on each frame; intensity="subtle" leaves it out.
Does it work with every variant and size?
Yes. The ring is drawn over the button's edge and the halo around it, so the variant's own fill and hover colors stay as they are. A filled default button shows the halo most; an outline button shows the ring most.
API Reference
GlowBorderButton
data-slot="glow-border-button-glow"
children?ReactNode
The label, inside the ring.
colors?string[]
The ring's colors, any CSS colors, in order around the button; the last one blends back into the first. By default two bright arcs of the primary color on a faint primary ring.
- Default
DEFAULT_COLORS
duration?number
How long one full turn of the ring takes, in milliseconds.
- Default
3000
focusableWhenDisabled?boolean
Whether the button should be focusable when disabled.
- Default
false
intensity?"subtle" | "medium" | "strong"
The halo around the ring: none at subtle, a soft one at medium,
a wider, brighter one at strong.
- Type
"subtle" | "medium" | "strong"- Default
"medium"
nativeButton?boolean
Whether the component renders a native <button> element when replacing it
via the render prop.
Set to false if the rendered element is not a button (for example, <div>).
- Default
true
paused?boolean
Stop the turn. The ring and its halo stay drawn, standing still.
- Default
false
render?ReactElement | ((props: object, state: object) => ReactElement)
Replace the host element or compose it with another component.
- Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string
Merged with the part's classes.
data-paused?string
Present when paused is set.
--glow-border-button-colorsstring
The ring's colors, comma-separated, around the button.
--glow-border-button-durationstring
One full turn (3s).
Related
- Pro
Flow Button
Glow & lightTurns only on hover, no halo
- Pro
Border Trace Button
Glow & lightDraws its edge once on hover
- Pro
Shimmer Button
SurfacesAnimated shimmer ring
- Pro
Neon Button
Glow & lightHalo that lights up on hover
- Pro
Gradient Button
SurfacesThe gradient fills the button
- Pro
Pulse Button
Motion & feedbackDraws the eye with a pulse instead