Beam Sweep Backdrop
Slow conic light beams rotating behind content, CSS-only and compositor-friendly.
- Category
- Backgrounds
- Added
- 2026-09-20
- Deps
- none
- Updated
- 2026-09-20
Backdrop
Beam Sweep
Props
"use client";
export function BeamSweepBackdrop({
children,
beams = 3,
speed = 18,
blur = 40,
vignette = true,
}: {
children?: React.ReactNode;
beams?: number;
speed?: number;
blur?: number;
/** Radial fade that pulls the beams away from the edges. */
vignette?: boolean;
}) {
return (
// `isolate` is load-bearing: the beams sit at a negative z-index, and
// position:relative alone does NOT create a stacking context, so without
// it they escape behind the page background entirely.
<div className="relative isolate overflow-hidden bg-[#07080b]">
{/*
* Own keyframes rather than Tailwind's `spin`: that one is only emitted
* when an animate-spin utility appears in the scanned source, which a
* copied-out component cannot rely on. Static by design — per-instance
* duration and direction go through inline style, never interpolated here.
*/}
<style>{"@keyframes beam-sweep-rotate { to { transform: translate(-50%, -50%) rotate(360deg); } }"}</style>
{Array.from({ length: beams }).map((_, i) => (
<div
key={i}
aria-hidden
className="absolute left-1/2 top-1/2 -z-10 aspect-square w-[180%] -translate-x-1/2 -translate-y-1/2"
style={{
background:
"conic-gradient(from " +
i * 120 +
"deg, transparent 0deg, #3d7bff " +
(14 + i * 6) +
"deg, transparent " +
(34 + i * 8) +
"deg, transparent 360deg)",
filter: "blur(" + blur + "px)",
opacity: 0.28 - i * 0.06,
// The keyframe carries the -50%/-50% translate itself, because an
// animation on transform replaces the class-based translate rather
// than composing with it.
animation:
"beam-sweep-rotate " +
(speed + i * 7) +
"s linear infinite" +
(i % 2 ? " reverse" : ""),
}}
/>
))}
{vignette && (
<div
aria-hidden
className="absolute inset-0 -z-10"
style={{
background:
"radial-gradient(circle at 50% 50%, transparent 30%, #07080b 78%)",
}}
/>
)}
<div className="relative">{children}</div>
</div>
);
}
About this background
Volumetric light behind a hero is usually reached for with canvas or a shader, and usually costs more than it returns. This gets there with rotating conic gradients: each layer is one narrow wedge of color against transparent, blurred hard enough that the gradient's edges disappear and only the glow remains. Because the layers turn at deliberately mismatched durations and alternating directions, the composite never settles into a recognisable loop — which is the thing that gives cheap ambient backgrounds away. Only transform and opacity animate, so the whole effect stays on the compositor with no main-thread work at all. Three implementation traps are worth knowing before adapting it. The wrapper needs `isolate`, because `position: relative` does not create a stacking context and the negative-z-index layers will otherwise escape behind the page background. The keyframes must be your own rather than Tailwind's `spin`, which is only emitted when an `animate-spin` utility appears in scanned source. And the keyframe has to restate the centering translate, since animating `transform` replaces the class-based translate instead of composing with it.
Curator’s note
Built for viberdy 2.0. Prime-ish, mismatched durations per beam are what stop the composite from looking like a single spinning sprite.
Pairs well with
Matched on shared tags and category — the entries most likely to be used alongside this one.
Orb Depth Field
backgroundsFloating orbs whose size, blur, opacity and speed all derive from one depth value.
Fractal Noise Drift
backgroundsGPU fractal noise drifting through a gradient light field, with no JS loop.
Animated Gradient Border Beam
backgroundsA light beam that continuously travels around a card's border.