Package Exports
- gradient-border-react
Readme
gradient-border-react
๐ Live demo โ
An animated gradient border that flows around any element. Tiny, dependency-free, and it respects
prefers-reduced-motionout of the box. Works with React 18 and React 19.
<GradientBorder colors={['#7C3AED', '#06B6D4', '#10B981']} radius={16} glow>
<div style={{ padding: 24 }}>Wrap me โจ</div>
</GradientBorder>No CSS file to import, no canvas, no requestAnimationFrame โ just a masked, rotating
conic-gradient driven by a registered @property. One <style> of keyframes is injected once,
and that's the whole runtime.
Install
From GitHub (always works):
pnpm add github:kea0811/gradient-border-reactFrom npm (when published to npm):
pnpm add gradient-border-reactPrefer npm or yarn?
npm install gradient-border-react/yarn add gradient-border-reactwork too.
react and react-dom are peer dependencies (^18 || ^19).
Quick start
import { GradientBorder, presets } from 'gradient-border-react';
export function ProfileCard() {
return (
<GradientBorder colors={presets.aurora} radius={16} borderWidth={2} background="#0d0d16">
<div style={{ padding: 24 }}>
<h3>Ada Lovelace</h3>
<p>The first programmer.</p>
</div>
</GradientBorder>
);
}That's it โ the border animates immediately. Wrap a card, a button, an avatar, an input; the gradient keeps flowing around whatever's inside.
Features
- ๐ Tiny & dependency-free โ a couple of inline styles and one injected keyframe block.
- ๐ Eight presets plus any custom color array you like.
- โฟ๏ธ Reduced-motion aware โ the ring freezes to a static gradient when the user asks for less motion, and the decorative layers are hidden from assistive tech.
- ๐งฉ Composable โ use the
<GradientBorder>component, or theuseGradientBorder()hook to paint the look onto your own markup. - โ๏ธ React 18 & 19 โ StrictMode-safe; all lifecycle lives in a single effect.
- ๐งช 100% test coverage, TypeScript strict mode, ESM + CJS + types.
API
<GradientBorder>
A <div> wrapper around your content. Accepts every standard div prop
(className, style, onClick, aria-*, a forwarded ref, โฆ) plus:
| Prop | Type | Default | Description |
|---|---|---|---|
colors |
string[] |
presets.aurora |
Colors the gradient cycles through. Treated as a loop; a single color is allowed. |
borderWidth |
number |
2 |
Border thickness, in pixels. |
radius |
number |
12 |
Corner radius, in pixels. |
duration |
number |
4 |
Seconds for one full rotation. Lower is faster. |
direction |
'cw' | 'ccw' |
'cw' |
Spin direction. |
paused |
boolean |
false |
Freeze the animation on its current frame. |
background |
string |
'transparent' |
Fill painted inside the border (turn the frame into a card). |
glow |
boolean |
false |
Add a soft, blurred glow of the same gradient behind the box. |
useGradientBorder(options?)
The component is a thin wrapper around this hook. It returns the inline styles for each layer, so you can compose the border onto any element you control:
import { useGradientBorder, presets } from 'gradient-border-react';
function FancyButton() {
const { ring, content } = useGradientBorder({ colors: presets.candy, radius: 999 });
return (
<div style={ring}>
<button style={content}>Click me</button>
</div>
);
}It returns { outer, glow, ring, content } โ all React.CSSProperties. options takes the same
fields as the component props above.
presets / presetNames
import { presets, presetNames } from 'gradient-border-react';
presets.sunset; // ['#F59E0B', '#EF4444', '#EC4899', '#8B5CF6']
presetNames; // ['aurora', 'sunset', 'ocean', 'candy', 'ember', 'mint', 'mono', 'rainbow']usePrefersReducedMotion()
The same accessibility hook the border uses internally, exported for convenience. Returns a boolean that updates live when the user's setting changes.
Accessibility
GradientBorder reads prefers-reduced-motion and renders a static gradient when reduced
motion is requested โ no flag needed. The glow and ring layers are purely decorative and marked
aria-hidden, so screen readers only ever see your content.
Browser support
The effect relies on CSS @property
to smoothly interpolate the gradient angle (Chrome/Edge 85+, Safari 16.4+, Firefox 128+). In older
engines the gradient still renders โ it just won't rotate, which is a perfectly fine fallback.
Live demo
See every prop in action: gradient-border-react.vercel.app
To run it locally:
pnpm install
pnpm build # build the library once
pnpm demo:dev # start the demo at http://localhost:5173Contributing
Issues and PRs are welcome. To hack on it:
pnpm install
pnpm test # run the suite
pnpm test:coverage # 100% across the board
pnpm build # ESM + CJS + .d.tsLicense
MIT ยฉ kea0811