Animated Border Glow Effect In Vanilla JavaScript – Border Beam Vanilla

Category: Animation , Javascript , Recommended | April 17, 2026
Authorjqueryscript
Last UpdateApril 17, 2026
LicenseMIT
Tags
Views0 views
Animated Border Glow Effect In Vanilla JavaScript – Border Beam Vanilla

Border Beam Vanilla is a Vanilla JavaScript library that decorates DOM elements with animated traveling border glows.

It ports the effect from Jakubantalik’s original border-beam concept to vanilla JS.

Features:

  • Adds a moving glow to an existing DOM element.
  • Supports small, medium, and line style presets.
  • Switches between colorful, mono, ocean, and sunset palettes.
  • Adapts the glow for dark, light, and system theme modes.
  • Reads the element border radius when you skip a manual value.
  • Updates the active instance through a controller object.
  • Fades the effect in and out through runtime state control.
  • Ships ESM, CJS, and TypeScript definitions.

See It In Action:

Use Cases:

  • Highlight a pricing card with a moving border accent.
  • Add motion to an icon button in a toolbar.
  • Accent a search bar with a bottom edge beam.
  • Draw attention to a settings panel or status box.

How to use it:

1. Install Border Beam Vanilla with NPM.

# NPM
$ npm install border-beam-vanilla

2. Import attachBorderBeam and target any element on your page.

<div class="feature-card" id="feature-card">
  <h3>Motion Layer</h3>
  <p>Animated focus treatment for modern interfaces.</p>
</div>
import { attachBorderBeam } from "border-beam-vanilla";
// OR
import { attachBorderBeam } from "./dist/index.es.js";
// Select the existing element that should receive the beam effect
const featureCard = document.querySelector("#feature-card");
// Attach the beam with a medium preset and an ocean palette
const featureCardBeam = attachBorderBeam(featureCard, {
  size: "md",
  colorVariant: "ocean",
  theme: "dark",
  strength: 0.85
});
// Keep the controller if you want to update or destroy the instance later
window.featureCardBeam = featureCardBeam;

3. The sm preset fits icon buttons and compact controls.

<button class="icon-action" id="icon-action" type="button">+</button>
// Attach a compact beam to a small action button
attachBorderBeam(document.querySelector("#icon-action"), {
  size: "sm",
  colorVariant: "sunset",
  theme: "dark"
});

4. The line preset focuses motion on the bottom edge. It’s great for search bars and command inputs.

<div class="search-shell" id="search-shell">
  <svg viewBox="0 0 24 24" aria-hidden="true">
    <circle cx="11" cy="11" r="8"></circle>
    <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
  </svg>
  <span>Search components</span>
</div>
// Attach the bottom edge beam to a search style surface
attachBorderBeam(document.querySelector("#search-shell"), {
  size: "line",
  colorVariant: "colorful",
  theme: "dark",
  duration: 2.4,
  borderRadius: 20
});

5. Use createBorderBeam() if you want the package to create the target <div> for you.

// Create a new decorated div
const noticeBeam = createBorderBeam({
  size: "md",
  colorVariant: "colorful",
  theme: "dark"
});
// Add your own content after the element is created
noticeBeam.element.className = "notice-box";
noticeBeam.element.innerHTML = `
  <strong>Export Complete</strong>
  <p>Your asset bundle is ready for review.</p>
`;
// Insert the generated element into the page
document.body.appendChild(noticeBeam.element);
6. Update, pause, resume, and destroy the effect:
// Attach the beam and store the controller
const settingsBeam = attachBorderBeam(document.querySelector("#settings-panel"), {
  size: "md",
  colorVariant: "colorful",
  theme: "dark"
});
// Fade the effect out
settingsBeam.setActive(false);
// Fade the effect back in
settingsBeam.setActive(true);
// Update the active instance with a new palette and lower strength
settingsBeam.update({
  colorVariant: "mono",
  strength: 0.55
});
// Remove the effect and clean up observers, style tags, and bloom layers
settingsBeam.destroy();

7. All configuration options.

  • size ("sm" | "md" | "line"): Selects the beam preset. Default: "md".
  • colorVariant ("colorful" | "mono" | "ocean" | "sunset"): Selects the color palette. Default: "colorful".
  • theme ("dark" | "light" | "auto"): Selects the surface theme. Default: "dark".
  • staticColors (boolean): Stops hue rotation. Mono mode stays static even if you skip this value. Default: false.
  • duration (number): Sets the animation cycle in seconds. Default: 1.96 for sm and md. Default: 2.4 for line.
  • active (boolean): Starts the instance in the active state. Default: true.
  • borderRadius (number): Sets the border radius in pixels. The runtime reads the computed element radius when you skip this value.
  • brightness (number): Sets the glow brightness multiplier. Default: 1.3.
  • saturation (number): Sets the glow saturation multiplier. The runtime uses preset values when you skip this value.
  • hueRange (number): Sets the hue rotation range in degrees. Default: 30. The line preset caps the final value at 13.
  • strength (number): Sets effect opacity from 0 to 1. Default: 1.
  • onActivate (() => void): Runs after the fade in animation completes.
  • onDeactivate (() => void): Runs after the fade out animation completes.

8. API methods.

import {
  attachBorderBeam,
  createBorderBeam,
  resolveSystemTheme,
  resolveBorderBeamOptions,
  resolveTheme,
  detectBorderRadius
} from "border-beam-vanilla";
// Attach the beam to an existing DOM element
const toolbarBeam = attachBorderBeam(document.querySelector("#toolbar"), {
  size: "sm",
  colorVariant: "sunset",
  theme: "dark"
});
// Update the current instance with a new config object
toolbarBeam.update({
  colorVariant: "ocean",
  strength: 0.7
});
// Toggle the current instance state
toolbarBeam.setActive(false);
toolbarBeam.setActive(true);
// Remove the current instance from the element
toolbarBeam.destroy();
// Create a new decorated div and return the controller plus the element
const bannerBeam = createBorderBeam({
  size: "md",
  colorVariant: "colorful"
});
document.body.appendChild(bannerBeam.element);
// Read the current system theme from matchMedia
const systemTheme = resolveSystemTheme();
// Resolve a theme value from the input theme and the system fallback
const themeValue = resolveTheme("auto", systemTheme);
// Read the numeric border radius from an element
const detectedRadius = detectBorderRadius(document.querySelector("#toolbar"));
// Resolve the final runtime options for an element and config object
const resolvedOptions = resolveBorderBeamOptions(document.querySelector("#toolbar"), {
  size: "line",
  theme: "auto"
});
console.log(systemTheme, themeValue, detectedRadius, resolvedOptions);

FAQs:

Q: Does border-beam-vanilla need React or another framework?
A: No. The API works on plain HTMLElement values. You can call it from any stack that exposes DOM access.

Q: Why does the beam not show up in one browser?
A: The effect depends on modern CSS features such as @property, conic gradients, and mask composition. Target current Chrome, Safari, and Firefox releases.

Q: How do I stop the beam on an inactive panel?
A: Keep the controller from attachBorderBeam(). Call setActive(false) when the panel loses focus or leaves view.

Q: Can I keep the radius from my own CSS?
A: Yes. Skip borderRadius and let the runtime read the computed value. Pass a number if you need a fixed radius.

You Might Be Interested In:


Leave a Reply