光る枠線をReactで実装!border-beamの使い方
2010年代初頭、私たちはボタンを一つ光らせるためだけに巨大なスプライト画像を切り出し、重たいJavaScriptのタイマーを回していた。今思えば苦笑してしまうような力技だが、当時はそれが「リッチなユーザー体験」の最前線だったのだ。その後、フラットデザインの波がすべてを平坦に塗り潰した時期を経て、近年再びUIに「光」や「動き」を取り入れるトレンドが戻ってきている。VercelやLinearといったモダンなSaaSの画面を見れば、その変化は一目瞭然だろう。
しかし、現代の「光」は昔の過剰な装飾とは違う。要素の輪郭を静かに這うような、極めて洗練されたマイクロインタラクションだ。
境界線を走る光を「正しく」実装する難しさ
あの「枠線を光が走るエフェクト」をいざ自分で実装しようとすると、意外と骨が折れる。conic-gradientを回転させ、maskプロパティで境界線部分だけを切り抜くのが定石だが、内包する要素の角丸(border-radius)とピクセル単位で合わせる微調整は、しばしば泥臭い職人芸になりがちだ。
そこで今回紹介したいのが、React向けの軽量コンポーネント「border-beam」である。このライブラリの最大の功績は、複雑なCSSのハックを完全に隠蔽し、宣言的なReactコンポーネントとして昇華させた点にある。使い方は拍子抜けするほどシンプルだ。
import { BorderBeam } from 'border-beam';
export function GlowingCard() {
return (
<BorderBeam size="md" colorVariant="ocean">
<div style={{ padding: 32, borderRadius: 16 }}>
次世代のUI体験
</div>
</BorderBeam>
);
}
驚くべきは、ラッパーとして機能するBorderBeamが、最初の子要素のborder-radiusをDOMから自動検出し、光の軌道を自動的に最適化してくれることだ。親の都合で子のスタイルを汚染することなく、純粋なレイヤーとして振る舞う。
モダンなアプローチがもたらす恩恵
既存の手法と本ライブラリの違いを整理すると、なぜ今これが注目に値するのかが見えてくる。
| アプローチ | 実装の手間 | 角丸への追従 | パフォーマンス |
|---|---|---|---|
| CSS自作 | 大(勾配やマスクの微調整) | 固定値で手動調整 | 実装方法に依存 |
| SVGアニメ | 中(パス計算と描画) | パスの再生成が必要 | 良好 |
| border-beam | 極小(ラップするだけ) | 自動検出・完全追従 | CSS @propertyによるGPU駆動 |
内部の実装も非常にモダンだ。光の筋(::after)や内側のグロウ(::before)、外側のブルーム効果のレイヤーは、すべてpointer-events: noneの絶対配置で重ね合わされている。コンテンツのクリックやホバーを一切邪魔しない。さらに、アニメーションにはCSSの@propertyを利用しており、メインスレッドをブロックしないGPUアクセラレーションの効いた滑らかな描画を実現している。
プロダクトに馴染む細やかなAPI設計
単なる「目を引くおもちゃ」で終わらないのが、このライブラリの秀逸なところだ。実運用を見据えたAPI設計が心憎い。
例えば、検索バーの下部だけを光らせるsize="line"や、ダークモード/ライトモードを自動検知するtheme="auto"といったプリセット。さらには、ユーザーの操作に応じてエフェクトのオン/オフを切り替えるためのactiveプロパティも備わっている。しかも、状態が切り替わる際にはブツッと途切れるのではなく、なめらかにフェードイン・フェードアウトする。プロダクトに組み込む際の「かゆいところ」にしっかりと手が届いているのだ。
結び
UIのトレンドは常に揺り戻しを繰り返すが、現代のそれは確かなパフォーマンスと設計の基盤の上に成り立っている。数行のコードで魔法のような質感をまとえるこのツールは、あなたのプロダクトをまた一段、プロフェッショナルなものに引き上げてくれるはずだ。
参考リポジトリ: Jakubantalik/border-beam