border-beam-vue
v1.0.0
Published
Animated border beam effect for Vue 3
Downloads
108
Maintainers
Readme
border-beam-vue
Animated border beam effect for Vue 3. A lightweight component that adds a GPU-accelerated traveling glow animation around any element — cards, buttons, inputs, or search bars.
Install
pnpm add border-beam-vueQuick start
<script setup>
import { BorderBeam } from 'border-beam-vue'
</script>
<template>
<BorderBeam>
<div style="padding: 32px; border-radius: 16px; background: #1d1d1d">
Your content here
</div>
</BorderBeam>
</template>The component wraps your content and overlays the animated beam. It auto-detects the border-radius of the first child element.
Sizes
<!-- Full border glow (default) -->
<BorderBeam size="md"><Card /></BorderBeam>
<!-- Compact glow for small buttons -->
<BorderBeam size="sm"><IconButton /></BorderBeam>
<!-- Bottom-only traveling glow for inputs / search bars -->
<BorderBeam size="line"><SearchBar /></BorderBeam>Color variants
<BorderBeam color-variant="colorful" /> <!-- Rainbow spectrum (default) -->
<BorderBeam color-variant="mono" /> <!-- Grayscale -->
<BorderBeam color-variant="ocean" /> <!-- Blue-purple tones -->
<BorderBeam color-variant="sunset" /> <!-- Orange-yellow-red tones -->All variants except mono animate through a hue-shift cycle.
Theme
<BorderBeam theme="dark" /> <!-- Dark background (default) -->
<BorderBeam theme="light" /> <!-- Light background -->
<BorderBeam theme="auto" /> <!-- Follows system prefers-color-scheme -->Strength
<BorderBeam :strength="0.7"> <!-- 70% intensity -->
<Card />
</BorderBeam>strength accepts 0 (invisible) to 1 (full intensity, default).
Play / pause
<script setup>
import { ref } from 'vue'
const active = ref(true)
</script>
<template>
<BorderBeam
:active="active"
@deactivate="console.log('faded out')"
>
<Card />
</BorderBeam>
<button @click="active = !active">Toggle</button>
</template>Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| size | 'sm' \| 'md' \| 'line' | 'md' | Size/type preset |
| color-variant | 'colorful' \| 'mono' \| 'ocean' \| 'sunset' | 'colorful' | Color palette |
| theme | 'dark' \| 'light' \| 'auto' | 'dark' | Background adaptation |
| strength | number | 1 | Effect opacity (0–1), only affects beam layers |
| duration | number | 1.96 / 2.4 | Animation cycle duration in seconds |
| active | boolean | true | Whether the animation is playing |
| border-radius | number | auto-detected | Custom border radius in px |
| brightness | number | 1.3 | Glow brightness multiplier |
| saturation | number | 1.2 | Glow saturation multiplier |
| hue-range | number | 30 | Hue rotation range in degrees |
| static-colors | boolean | false | Disable hue-shift animation |
All standard <div> attributes — class, style, data-*, etc. — are forwarded via v-bind="$attrs".
Events
| Event | Description |
|-------|-------------|
| @activate | Emitted when the fade-in animation completes |
| @deactivate | Emitted when the fade-out animation completes |
Exposed ref
<script setup>
import { ref } from 'vue'
const beam = ref()
// beam.value.el → the underlying HTMLDivElement
</script>
<template>
<BorderBeam ref="beam"><Card /></BorderBeam>
</template>How it works
BorderBeam renders a wrapper <div> with three purely decorative layers:
::after— beam stroke (conic gradient masked to the border path)::before— inner glow layer (radial gradients)[data-beam-bloom]— outer bloom / halo element
All layers use position: absolute and pointer-events: none, so they never interfere with content, focus, or keyboard navigation. Animations use CSS @property for smooth GPU-accelerated transitions.
Per-instance CSS is scoped to a unique [data-beam="<id>"] attribute, so any number of beams can coexist on a page without collisions.
Project structure
border-beam-vue/
├── src/
│ ├── index.ts # Public exports
│ ├── BorderBeam.vue # Vue 3 component
│ ├── types.ts # TypeScript type definitions
│ └── styles.ts # CSS generation engine (framework-agnostic)
├── demo/ # Vite + Vue 3 demo site
├── dist/ # Build output (ESM + CJS + types)
├── package.json
├── LICENSE
└── README.mdRequirements
- Vue 3.3+
- Modern browser with CSS
@propertysupport (Chrome 85+, Safari 15.4+, Firefox 128+)
Accessibility
All effect layers are purely decorative (pointer-events: none, aria-hidden="true" on the bloom element). They do not affect keyboard navigation, focus management, or screen readers.
To respect prefers-reduced-motion, add this to your global CSS:
@media (prefers-reduced-motion: reduce) {
[data-beam] { animation: none !important; }
[data-beam]::after,
[data-beam]::before,
[data-beam] [data-beam-bloom] { display: none !important; }
}Credits
This is a Vue 3 port of the original border-beam React component by Jakub Antalik. The CSS generation engine (src/styles.ts) is unchanged from the original work.
