A small light that travels around any element's border at a steady pace. Subtle, premium, never distracting.
Featured
Studio plan
A light travels the border.
Customize
Usage
import { BorderBeam } from "@/components/motionkit/border-beam";
{/* any element with position: relative and a matching radius */}
<div className="relative rounded-2xl border p-6">
<h3>Studio plan</h3>
<BorderBeam />
</div>Motion
The exact curves this component runs, plotted with Motion's own maths.
Lap
Runs on its own
Works in the App Router as is. Requires Tailwind CSS v4.
npm install motionSave as components/motionkit/border-beam.tsx.
"use client";
import { motion, useReducedMotion } from "motion/react";
type BorderBeamProps = {
/** Length of the beam in pixels. */
size?: number;
/** Seconds for one lap of the border. */
duration?: number;
/** Seconds to wait before the first lap. Offset several beams to stagger them. */
delay?: number;
/** Colour at the head of the beam. */
colorFrom?: string;
/** Colour the tail fades through. */
colorTo?: string;
/** Border thickness in pixels. */
borderWidth?: number;
/** Corner radius of the element it sits in, so the beam follows the curve. */
radius?: number;
/** Travel anticlockwise. */
reverse?: boolean;
};
/**
* A small light that travels around the border of whatever it sits in.
* Place it as the last child of any element with position: relative.
*/
export function BorderBeam({
size = 80,
duration = 6,
delay = 0,
colorFrom = "#5FAEB4",
colorTo = "#A56D5B",
borderWidth = 1.5,
radius = 16,
reverse = false,
}: BorderBeamProps) {
const reduceMotion = useReducedMotion();
if (reduceMotion) return null;
return (
<div
aria-hidden
className="pointer-events-none absolute inset-0"
style={{
borderRadius: radius,
// cut the middle out, so the beam only ever shows on the border
padding: borderWidth,
WebkitMask: "linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0)",
WebkitMaskComposite: "xor",
maskComposite: "exclude",
}}
>
{/* the beam rides a rounded-rectangle path, so it keeps a steady speed on any shape */}
<motion.div
className="absolute aspect-square"
style={{
width: size,
offsetPath: `rect(0 auto auto 0 round ${radius}px)`,
// the head leads in the direction of travel, with the tail fading out behind it
background: `linear-gradient(to ${reverse ? "right" : "left"}, ${colorFrom}, ${colorTo}, transparent)`,
}}
initial={{ offsetDistance: reverse ? "100%" : "0%" }}
animate={{ offsetDistance: reverse ? ["100%", "0%"] : ["0%", "100%"] }}
transition={{ duration, delay, repeat: Infinity, ease: "linear" }}
/>
</div>
);
}
| Prop | Type | Default | Description |
|---|---|---|---|
| size | number | 80 | Length of the beam in pixels. |
| duration | number | 6 | Seconds for one lap of the border. |
| delay | number | 0 | Seconds before the first lap. Offset several beams to stagger them. |
| colorFrom / colorTo | string | "#5FAEB4" / "#A56D5B" | Colour at the head of the beam, and the colour its tail fades through. |
| borderWidth | number | 1.5 | Border thickness in pixels. |
| radius | number | 16 | Corner radius of the parent, so the beam follows the curve. |
| reverse | boolean | false | Travel anticlockwise. |
Pro plan
$12/mo
Every component, every update.
Orbit Border
A container whose border carries a light that travels around it.
Realtime sync
Move your cursor across this card.
Spotlight Card
A card with a soft glow that tracks the pointer across its surface.
Fast
Secure
Global
Typed
Spotlight Grid
One soft beam follows the pointer across a grid, lighting the borders and faces of the cards it passes.