DEMO
CODE
<div class="demo-stage spk-stage"> <h3 class="spk-text" id="spk-text">Sparkles<span class="spk-layer" id="spk-layer" aria-hidden="true"></span></h3> </div>
.spk-stage { display:flex; align-items:center; justify-content:center; padding:2rem; background:#0B0B10; min-height:280px; }
.spk-text { position:relative; margin:0; font-family:'Oswald',sans-serif; font-size:3.4rem; font-weight:600; letter-spacing:.04em;
background:linear-gradient(90deg,#fff 0%,#F9C6E0 50%,#fff 100%); -webkit-background-clip:text; background-clip:text; color:transparent; }
.spk-layer { position:absolute; inset:-18px; pointer-events:none; }
.spk-star { position:absolute; width:14px; height:14px; opacity:0; animation: spk-twinkle 1.1s ease-in-out forwards; }
.spk-star svg { width:100%; height:100%; display:block; }
@keyframes spk-twinkle {
0% { opacity:0; transform:scale(0) rotate(0deg); }
50% { opacity:1; transform:scale(1) rotate(90deg); }
100% { opacity:0; transform:scale(0) rotate(180deg); }
}
@media (prefers-reduced-motion: reduce) {
.spk-layer { display:none; }
}
(function(){
var layer = document.getElementById('spk-layer');
if (!layer || window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
var COLORS = ['#E91B89', '#F9CB28', '#5BAADE', '#FFFFFF'];
var SVG = '<svg viewBox="0 0 24 24"><path d="M12 0l2.6 9.4L24 12l-9.4 2.6L12 24l-2.6-9.4L0 12l9.4-2.6z" fill="currentColor"/></svg>';
var POOL = 10, stars = [];
for (var i = 0; i < POOL; i++) {
var s = document.createElement('span');
s.className = 'spk-star'; s.innerHTML = SVG;
layer.appendChild(s); stars.push(s);
}
var k = 0;
function spawn(){
var s = stars[k++ % POOL];
var size = 8 + Math.random() * 12;
s.style.width = s.style.height = size + 'px';
s.style.left = (Math.random() * 100) + '%';
s.style.top = (Math.random() * 100) + '%';
s.style.color = COLORS[Math.floor(Math.random() * COLORS.length)];
s.style.animation = 'none'; void s.offsetWidth; s.style.animation = '';
}
setInterval(function(){ if (!document.hidden) spawn(); }, 180);
})();
AI PROMPT
見出しのまわりに小さな星がランダムに現れては消える Sparkles Text を作って。見出しに position:relative を付け、その中に aria-hidden="true" で pointer-events:none の星用レイヤー(inset:-18px で文字より少し広い範囲)を置く。星は4方向に尖った形の SVG(path で描く)を span に入れ、@keyframes で scale(0) rotate(0) → scale(1) rotate(90deg)・不透明 → scale(0) rotate(180deg)・透明 を1.1秒で1回だけ再生する。星は10個だけ最初に作って使い回す(新しく作り続けると要素が増え続けるため):180msごとに次の星を選び、大きさ8〜20px・位置0〜100%・色をランダムに変えてから animation を一度 none にして強制リフロー(void el.offsetWidth)し、再生し直す。タブが裏にある時(document.hidden)は生成しない。文字自体は白〜淡いピンクのグラデーションを background-clip:text で入れる。@media (prefers-reduced-motion: reduce) では星のレイヤーを表示しない。 Acceptance criteria: works with prefers-reduced-motion (animation disabled), zero console errors, zero layout shift
AIエージェントでの実装ガイド → Claude Code でWebアニメーションを実装する
BOOKS · PR · AMAZON
※当サイトはAmazonアソシエイトプログラムの参加者です。リンクから商品をご購入いただくと、当方に紹介料が発生します。
学びを止めない · AMAZONサブスク
※当サイトはAmazonアソシエイトプログラムの参加者です。リンクから商品をご購入いただくと、当方に紹介料が発生します。
見出しや強調したい語のまわりに、小さな星がランダムに現れては消えるきらめきの演出です。Magic UI にも同じ名前のコンポーネント(Sparkles Text)があり、新機能の告知やキャンペーン名のように「特別感」を出したい文字に使われます。
当サイトの Animated Shiny Text は文字の表面を光が横切る演出、Glow Pulse Text は文字自体が脈打つように光る演出、Confetti Burst はクリックで紙吹雪が飛び散る演出です。本ページは文字の外側に小さな光を散らす別テーマで、文字の読みやすさを変えずに装飾できます。
要点は星の数を固定して使い回すことです。一定間隔で要素を作り続けると、表示時間に比例して重くなります。表示し続ける見出しに使うなら、この使い回しと、タブが裏にある間は止める処理を必ず入れてください。
星の要素を作り続けるとどうなりますか?
180msごとに新しい要素を追加して消さずにいると、1分で300個以上の要素がたまり、描画が重くなります。本実装は最初に10個だけ作って順番に使い回すため、何時間表示しても要素数は10個のままです。削除して作り直す方式より、ブラウザの処理も少なく済みます。
animation を none にしてから戻すのはなぜですか?
同じ要素に同じアニメーションを指定し直しても、ブラウザは「変わっていない」と判断して再生しません。一度 animation を none にし、offsetWidth を読んで描画を確定させてから空文字に戻すと、CSS に書いたアニメーションが最初から再生されます。
コードは無料で使えますか?
はい。Motion LabのコードスニペットとAIプロンプトは、クレジット表記なしで自由に使えます。コピーしてそのままプロジェクトに利用できます。