border-beam-react

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

border-beam-react

border-beam-react

Skill by ara.so — Daily 2026 Skills collection.
border-beam
is a lightweight React component that renders an animated traveling glow/beam effect around any element — cards, buttons, inputs, search bars, or any container. It uses CSS
@property
for GPU-accelerated animations with no runtime animation libraries required.
ara.so提供的Skill — 2026每日技能合集。
border-beam
是一款轻量级React组件,可为任意元素(卡片、按钮、输入框、搜索栏或任何容器)渲染动态移动的光晕/光束效果。它使用CSS
@property
实现GPU加速动画,无需依赖运行时动画库。

Installation

安装

bash
npm install border-beam
Requirements:
  • React 18+
  • Modern browser: Chrome 85+, Safari 15.4+, Firefox 128+
bash
npm install border-beam
要求:
  • React 18及以上版本
  • 现代浏览器:Chrome 85+、Safari 15.4+、Firefox 128+

Basic Usage

基本用法

tsx
import { BorderBeam } from 'border-beam';

function App() {
  return (
    <BorderBeam>
      <div style={{ padding: 32, borderRadius: 16, background: '#1d1d1d' }}>
        Your content here
      </div>
    </BorderBeam>
  );
}
BorderBeam
wraps your content and auto-detects the
border-radius
of the first child element. All effect layers use
pointer-events: none
so they never block interaction.
tsx
import { BorderBeam } from 'border-beam';

function App() {
  return (
    <BorderBeam>
      <div style={{ padding: 32, borderRadius: 16, background: '#1d1d1d' }}>
        你的内容放在这里
      </div>
    </BorderBeam>
  );
}
BorderBeam
会包裹你的内容,并自动检测第一个子元素的
border-radius
。所有效果层都使用
pointer-events: none
,因此绝不会阻挡交互。

Size Presets

尺寸预设

tsx
// Full border glow (default) — for cards, panels
<BorderBeam size="md">
  <Card />
</BorderBeam>

// Compact glow — for small elements like icon buttons
<BorderBeam size="sm">
  <IconButton />
</BorderBeam>

// Bottom-only traveling glow — ideal for search bars, inputs
<BorderBeam size="line">
  <SearchBar />
</BorderBeam>
tsx
// 完整边框光晕(默认)——适用于卡片、面板
<BorderBeam size="md">
  <Card />
</BorderBeam>

// 紧凑光晕——适用于图标按钮等小型元素
<BorderBeam size="sm">
  <IconButton />
</BorderBeam>

// 仅底部移动光晕——非常适合搜索栏、输入框
<BorderBeam size="line">
  <SearchBar />
</BorderBeam>

Color Variants

颜色变体

tsx
<BorderBeam colorVariant="colorful" /> {/* Rainbow spectrum (default), animates hue */}
<BorderBeam colorVariant="mono" />     {/* Grayscale, no hue animation */}
<BorderBeam colorVariant="ocean" />    {/* Blue-purple tones */}
<BorderBeam colorVariant="sunset" />   {/* Orange-yellow-red tones */}
All variants except
mono
animate through a hue-shift cycle by default.
tsx
<BorderBeam colorVariant="colorful" /> {/* 彩虹光谱(默认),动态变换色相 */}
<BorderBeam colorVariant="mono" />     {/* 灰度模式,无色相动画 */}
<BorderBeam colorVariant="ocean" />    {/* 蓝紫色调 */}
<BorderBeam colorVariant="sunset" />   {/* 橙黄红色调 */}
mono
外,所有变体默认都会进行色相偏移循环动画。

Theme (Dark / Light / Auto)

主题(深色/浅色/自动)

tsx
<BorderBeam theme="dark" />  {/* Default — for dark backgrounds */}
<BorderBeam theme="light" /> {/* For light backgrounds */}
<BorderBeam theme="auto" />  {/* Detects system prefers-color-scheme */}
tsx
<BorderBeam theme="dark" />  {/* 默认——适用于深色背景 */}
<BorderBeam theme="light" /> {/* 适用于浅色背景 */}
<BorderBeam theme="auto" />  {/* 自动检测系统的prefers-color-scheme设置 */}

Controlling Intensity

强度控制

tsx
// strength: 0 (invisible) to 1 (full, default) — only affects beam layers
<BorderBeam strength={0.6}>
  <Card />
</BorderBeam>

// brightness and saturation multipliers
<BorderBeam brightness={1.5} saturation={1.4}>
  <Card />
</BorderBeam>
tsx
// strength: 0(不可见)至1(完全显示,默认值)——仅影响光束层
<BorderBeam strength={0.6}>
  <Card />
</BorderBeam>

// 亮度和饱和度乘数
<BorderBeam brightness={1.5} saturation={1.4}>
  <Card />
</BorderBeam>

Play / Pause with Callbacks

通过回调控制播放/暂停

tsx
import { useState } from 'react';
import { BorderBeam } from 'border-beam';

function AnimatedCard() {
  const [active, setActive] = useState(true);

  return (
    <>
      <BorderBeam
        active={active}
        onActivate={() => console.log('Beam faded in')}
        onDeactivate={() => console.log('Beam faded out')}
      >
        <div style={{ padding: 32, borderRadius: 16, background: '#111' }}>
          Hover-activated beam
        </div>
      </BorderBeam>
      <button onClick={() => setActive(a => !a)}>Toggle Beam</button>
    </>
  );
}
tsx
import { useState } from 'react';
import { BorderBeam } from 'border-beam';

function AnimatedCard() {
  const [active, setActive] = useState(true);

  return (
    <>
      <BorderBeam
        active={active}
        onActivate={() => console.log('光束淡入完成')}
        onDeactivate={() => console.log('光束淡出完成')}
      >
        <div style={{ padding: 32, borderRadius: 16, background: '#111' }}>
          悬停触发光束
        </div>
      </BorderBeam>
      <button onClick={() => setActive(a => !a)}>切换光束</button>
    </>
  );
}

Custom Duration and Hue Range

自定义时长与色相范围

tsx
<BorderBeam
  duration={3.5}      // Animation cycle in seconds (default: 1.96 for md, 2.4 for line)
  hueRange={60}       // Hue rotation range in degrees (default: 30)
  staticColors={true} // Disable hue-shift entirely
>
  <Card />
</BorderBeam>
tsx
<BorderBeam
  duration={3.5}      // 动画周期(秒),默认值:md尺寸为1.96,line尺寸为2.4
  hueRange={60}       // 色相旋转范围(度),默认值:30
  staticColors={true} // 完全禁用色相偏移
>
  <Card />
</BorderBeam>

Custom Border Radius

自定义边框圆角

If auto-detection doesn't work (e.g., the radius is set via a CSS class), override it:
tsx
<BorderBeam borderRadius={24}>
  <div className="my-card">Content</div>
</BorderBeam>
如果自动检测失效(例如圆角通过CSS类设置),可以手动指定:
tsx
<BorderBeam borderRadius={24}>
  <div className="my-card">内容</div>
</BorderBeam>

Forwarded HTML Attributes

透传HTML属性

The wrapper
<div>
forwards all standard
HTMLDivElement
attributes:
tsx
<BorderBeam
  className="my-wrapper"
  style={{ display: 'inline-block' }}
  data-testid="beam-card"
>
  <Card />
</BorderBeam>
包裹用的
<div>
会透传所有标准
HTMLDivElement
属性:
tsx
<BorderBeam
  className="my-wrapper"
  style={{ display: 'inline-block' }}
  data-testid="beam-card"
>
  <Card />
</BorderBeam>

Common Patterns

常见用法示例

Hover-activated beam

悬停触发光束

tsx
import { useState } from 'react';
import { BorderBeam } from 'border-beam';

function HoverCard() {
  const [hovered, setHovered] = useState(false);

  return (
    <BorderBeam active={hovered} strength={0.85} colorVariant="ocean">
      <div
        onMouseEnter={() => setHovered(true)}
        onMouseLeave={() => setHovered(false)}
        style={{ padding: 24, borderRadius: 12, background: '#0f0f0f' }}
      >
        Hover me
      </div>
    </BorderBeam>
  );
}
tsx
import { useState } from 'react';
import { BorderBeam } from 'border-beam';

function HoverCard() {
  const [hovered, setHovered] = useState(false);

  return (
    <BorderBeam active={hovered} strength={0.85} colorVariant="ocean">
      <div
        onMouseEnter={() => setHovered(true)}
        onMouseLeave={() => setHovered(false)}
        style={{ padding: 24, borderRadius: 12, background: '#0f0f0f' }}
      >
        悬停我
      </div>
    </BorderBeam>
  );
}

Search bar with line beam

带线条光束的搜索栏

tsx
import { BorderBeam } from 'border-beam';

function SearchInput() {
  return (
    <BorderBeam size="line" colorVariant="sunset" theme="dark">
      <input
        type="text"
        placeholder="Search..."
        style={{
          padding: '12px 16px',
          borderRadius: 8,
          background: '#1a1a1a',
          border: '1px solid #333',
          color: '#fff',
          width: 320,
        }}
      />
    </BorderBeam>
  );
}
tsx
import { BorderBeam } from 'border-beam';

function SearchInput() {
  return (
    <BorderBeam size="line" colorVariant="sunset" theme="dark">
      <input
        type="text"
        placeholder="搜索..."
        style={{
          padding: '12px 16px',
          borderRadius: 8,
          background: '#1a1a1a',
          border: '1px solid #333',
          color: '#fff',
          width: 320,
        }}
      />
    </BorderBeam>
  );
}

Light theme card

浅色主题卡片

tsx
import { BorderBeam } from 'border-beam';

function LightCard() {
  return (
    <BorderBeam theme="light" colorVariant="colorful" strength={0.8}>
      <div style={{ padding: 32, borderRadius: 16, background: '#f5f5f5' }}>
        Light mode card
      </div>
    </BorderBeam>
  );
}
tsx
import { BorderBeam } from 'border-beam';

function LightCard() {
  return (
    <BorderBeam theme="light" colorVariant="colorful" strength={0.8}>
      <div style={{ padding: 32, borderRadius: 16, background: '#f5f5f5' }}>
        浅色模式卡片
      </div>
    </BorderBeam>
  );
}

Reduced motion accessibility

减少动画的无障碍适配

The component itself does not automatically respond to
prefers-reduced-motion
. Handle it in the consumer:
tsx
import { useReducedMotion } from 'framer-motion'; // or your own hook
import { BorderBeam } from 'border-beam';

function AccessibleCard() {
  const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  return (
    <BorderBeam active={!reduceMotion}>
      <Card />
    </BorderBeam>
  );
}
组件本身不会自动响应
prefers-reduced-motion
,需要在业务代码中处理:
tsx
import { useReducedMotion } from 'framer-motion'; // 或自定义钩子
import { BorderBeam } from 'border-beam';

function AccessibleCard() {
  const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  return (
    <BorderBeam active={!reduceMotion}>
      <Card />
    </BorderBeam>
  );
}

Full Props Reference

完整属性参考

PropTypeDefaultDescription
children
ReactNode
Content to wrap
size
'sm' | 'md' | 'line'
'md'
Size/type preset
colorVariant
'colorful' | 'mono' | 'ocean' | 'sunset'
'colorful'
Color palette
theme
'dark' | 'light' | 'auto'
'dark'
Background adaptation
strength
number
1
Beam opacity 0–1, does not affect children
duration
number
1.96
/
2.4
Animation cycle in seconds
active
boolean
true
Play/pause with fade transition
borderRadius
number
auto-detectedOverride border radius in px
brightness
number
1.3
Glow brightness multiplier
saturation
number
1.2
Glow saturation multiplier
hueRange
number
30
Hue rotation range in degrees
staticColors
boolean
false
Disable hue-shift animation
className
string
Class on wrapper div
style
CSSProperties
Inline styles on wrapper div
onActivate
() => void
Called when fade-in completes
onDeactivate
() => void
Called when fade-out completes
属性类型默认值描述
children
ReactNode
要包裹的内容
size
'sm' | 'md' | 'line'
'md'
尺寸/类型预设
colorVariant
'colorful' | 'mono' | 'ocean' | 'sunset'
'colorful'
配色方案
theme
'dark' | 'light' | 'auto'
'dark'
背景适配模式
strength
number
1
光束透明度(0–1),不影响子元素
duration
number
1.96
/
2.4
动画周期(秒)
active
boolean
true
控制播放/暂停,带淡入淡出过渡
borderRadius
number
自动检测手动指定边框圆角(像素)
brightness
number
1.3
光晕亮度乘数
saturation
number
1.2
光晕饱和度乘数
hueRange
number
30
色相旋转范围(度)
staticColors
boolean
false
禁用色相偏移动画
className
string
包裹div的类名
style
CSSProperties
包裹div的内联样式
onActivate
() => void
淡入完成时触发的回调
onDeactivate
() => void
淡出完成时触发的回调

How It Works

工作原理

BorderBeam
renders a wrapper
<div>
with three effect layers — all
pointer-events: none
, absolutely positioned, never affecting layout or interaction:
  • ::after
    — beam stroke (conic gradient masked to the border edge)
  • ::before
    — inner glow layer
  • [data-beam-bloom]
    — outer bloom/glow child
    <div>
Animations use CSS
@property
for smooth, GPU-accelerated hue cycling.
BorderBeam
渲染一个包含三层效果的包裹
<div>
——所有层都设置
pointer-events: none
,绝对定位,绝不会影响布局或交互:
  • ::after
    — 光束描边(通过遮罩应用于边框边缘的圆锥渐变)
  • ::before
    — 内光晕层
  • [data-beam-bloom]
    — 外光晕/发光子
    <div>
动画使用CSS
@property
实现流畅的GPU加速色相循环。

Troubleshooting

常见问题排查

Beam not visible:
  • Ensure the child element has a visible
    background
    and
    border-radius
  • Check
    strength
    is not
    0
  • Verify
    active
    is
    true
Border radius not matching:
  • Pass
    borderRadius
    prop explicitly if the radius comes from a CSS class rather than inline style
Effect covers content / blocks clicks:
  • All layers are
    pointer-events: none
    by default — if this is happening, check for CSS conflicts in your wrapper
Animation not working in browser:
SSR / Next.js:
  • The component uses DOM APIs for border-radius detection; wrap in a client component (
    'use client'
    ) in Next.js App Router
光束不可见:
  • 确保子元素设置了可见的
    background
    border-radius
  • 检查
    strength
    值不为
    0
  • 确认
    active
    值为
    true
边框圆角不匹配:
  • 如果圆角通过CSS类而非内联样式设置,需手动传入
    borderRadius
    属性
效果覆盖内容/阻挡点击:
  • 所有层默认都设置
    pointer-events: none
    ,若出现此问题请检查包裹元素的CSS冲突
浏览器中动画不生效:
SSR / Next.js:
  • 组件使用DOM API检测边框圆角,在Next.js App Router中需包裹为客户端组件(添加
    'use client'