HTML / CSS
アニメーション
2026/02/21
2026/2/14
ヒーローエリアのタイトルに、光が流れるような動きを加えたい。
複数のtext-shadowを縦方向に重ね、それらをアニメーションで入れ替えることで、ネオンの残像が上下に流れ続けるタイトル表現を作っています。
HTMLはテキスト1行だけで完結します。
<div class="main-container">
<p>kumonosu</p>
</div>
body {
margin: 0;
}
.main-container {
display: grid;
place-content: center;
min-height: 100vh;
background-color: #000;
color: white;
margin: 0;
overflow: hidden;
padding: 20px;
box-sizing: border-box;
}
.main-container p {
--ani-duration: 1000ms;
--ani-timing-function: linear;
--shadow-dist: clamp(30px, 8vh, 60px);
--rgb-1: 255 255 255;
--rgb-2: 255 0 0;
--rgb-3: 0 0 255;
--rgb-4: 255 0 0;
--opacity-1: 0.5;
--opacity-2: 0.25;
--opacity-3: 0.15;
--opacity-4: 0;
font-family: "Allerta Stencil", sans-serif;
font-size: clamp(2rem, 12vw, 6rem);
text-transform: uppercase;
text-align: center;
margin: 0;
line-height: 1;
word-break: break-all;
text-shadow:
0 0 rgba(var(--rgb-1) / var(--opacity-1)),
0 0 rgba(var(--rgb-1) / var(--opacity-1)),
0 var(--shadow-dist) rgba(var(--rgb-2) / var(--opacity-2)),
0 calc(var(--shadow-dist) * -1) rgba(var(--rgb-2) / var(--opacity-2)),
0 calc(var(--shadow-dist) * 2) rgba(var(--rgb-3) / var(--opacity-3)),
0 calc(var(--shadow-dist) * -2) rgba(var(--rgb-3) / var(--opacity-3));
}
@media not (prefers-reduced-motion) {
.main-container p {
animation: ani-text var(--ani-duration) var(--ani-timing-function) infinite;
}
}
@keyframes ani-text {
to {
text-shadow:
0 var(--shadow-dist) rgba(var(--rgb-2) / var(--opacity-2)),
0 calc(var(--shadow-dist) * -1) rgba(var(--rgb-2) / var(--opacity-2)),
0 calc(var(--shadow-dist) * 2) rgba(var(--rgb-3) / var(--opacity-3)),
0 calc(var(--shadow-dist) * -2) rgba(var(--rgb-3) / var(--opacity-3)),
0 calc(var(--shadow-dist) * 3) rgba(var(--rgb-4) / var(--opacity-4)),
0 calc(var(--shadow-dist) * -3) rgba(var(--rgb-4) / var(--opacity-4));
}
}
https://fonts.bunny.net/css?family=allerta-stencil:400
テキストはtext-shadowを複数重ねて構成しています。白の基本影に加え、緑・青・ピンクの影を縦方向へ段階的に配置し、奥行きのある発光レイヤーを作っています。
アニメーションでは、これらの影の並び順と距離を@keyframesで入れ替えることで、光の層が上から下へ(または下から上へ)流れているように見せています。距離は--shadow-distで管理し、clamp()とvhを使って画面サイズに応じて自然に変化します。
フォントサイズもclamp()で可変にしているため、スマホからデスクトップまでバランスを保ちます。また、prefers-reduced-motionを尊重し、動きを抑制できるようにしています。
text-shadowを複数重ねて発光レイヤーを作成clamp()でフォントサイズと影距離をレスポンシブ制御prefers-reduced-motionでアニメ停止対応見た目は「色」「影の距離」「アニメ速度」で大きく変わります。
--rgb-2 / --rgb-3 / --rgb-4--shadow-dist--opacity-*--ani-duration--ani-timing-function影の段数を増やせば、より厚みのあるグロー表現にできます。
text-shadowを多数使うため、極端に大きな文字サイズや長文に適用すると描画負荷が上がります。ヒーローテキストなど短い単語向けの演出です。
また、word-break: break-allを使っているため、日本語や長い英単語では意図しない位置で改行される可能性があります。必要に応じて調整してください。