A luminous beam that travels the perimeter of a card or button.
Configurable speed, colour, and thickness — all CSS variables. Two files,
zero dependencies, CSP-safe. Respects prefers-reduced-motion.
One class does it. .es-sweep puts a beam on the border of
any element while it keeps its own background and text. This card sets a matching corner radius
via --es-radius.
The beam only rides the border band — content underneath stays perfectly legible.
<!-- one class + link the stylesheet -->
<article class="es-sweep" style="--es-radius:18px"> … </article>
Every knob is a CSS variable. Set them inline for one element, or globally for all. Each tile below overrides a different one.
<div class="es-sweep"
style="--es-color:#7CF29B; --es-color-2:#4FD8C4;
--es-speed:2s; --es-thickness:4px">…</div>
Pill or rounded, dark or light — set --es-radius to match the
shape and the beam follows the corners. Great for a primary call-to-action.
<button class="es-sweep" style="--es-radius:999px; --es-color:#7CF29B; --es-speed:3s">Ship it</button>
Skip the variables — reach for a modifier class. --reverse orbits
the other way; --calm and --urgent retune speed, arc, and
glow together.
<div class="es-sweep es-sweep--urgent">…</div> <div class="es-sweep es-sweep--reverse">…</div>
For nodes you build at runtime, edge-sweep.js exposes
window.EdgeSweep. Mount, retune, pause, or unmount — the handle is chainable.
// mount with options const beam = EdgeSweep.mount("#save-btn", { color:"#7CF29B", speed:3, thickness:2 }); // retune live, then pause / resume / remove beam.update({ speed:1.8, arc:120 }); beam.pause(); beam.resume(); beam.unmount(); // or declaratively — auto-mounted on load <div data-edge-sweep data-es-color="#FFB86B" data-es-speed="5">…</div>
Turn on “Reduce motion” in your OS and reload: the beam stops travelling and settles into a soft static gradient border. The element still reads as highlighted — nothing orbits, and the bloom layer is dropped. Motion is never forced on anyone.