GODRICH

CSS テキスト グラデーション アニメーション 9選 — 一行でコピペOK

css テキスト グラデーション アニメーションは、文字の中に流し込んだ色が動いたり光を放ったりして見える、background-clip:textやfilterだけで組める小さな演出です。この記事では9種類を選び、6〜25行のコードとして実装しました。

自動再生 · タイルを押すとその項目へ · すべて1つのzip

9つは派手さの順ではなく、グラデーションが文字の上で何をするかという順番に並べました。色そのものが流れていくもの(01・02)、光で強調するもの(03・04)、画面がずれたり表面が反射したりするもの(05・06)、文字が一つずつ点滅したり空洞になったりするもの(07・08)、最後は色相環そのものが回るもの(09)という流れです。デモの文言はただの例なので、実際に使うときは<h1>の中身だけ差し替えればコードはそのまま動きます。

01流れるグラデーション文字

文字にグラデーションをbackground-clip:textで流し込み、大きめのbackground-sizeの上でbackground-positionを左右に動かすと、色が文字の中を流れ続けているように見えます。LPヒーローの見出しやプロモバナーのコピーに向いています。

background-clip:textbackground-position2s
.flow {
  background: linear-gradient(90deg, $color, $subject-cream, $color, $subject-cream, $color);
  background-size: 300% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  animation: flow $duration $easing infinite;
}
@keyframes flow {
  0%   { background-position: 0% 50%; }
  100% { background-position: 100% 50%; }
}

02グラデーション角度移動

@propertyで型のカスタムプロパティを登録してlinear-gradient()の角度に入れ、0degから360degへkeyframesで回すと、グラデーション自体が文字の中で回転します。カードタイトルの強調や会員バッジの文言に向いています。

@property<angle>linear-gradient
@property --angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}
.spin {
  --angle: 0deg;
  background: linear-gradient(var(--angle), $color, $stage-orange, $color);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: rotate-angle $duration $easing infinite;
}
@keyframes rotate-angle { from { --angle: 0deg; } to { --angle: 360deg; } }

03ネオングロー文字

同じ文字をもう1枚背後に重ねてfilter:blur()だけをかけ、ぼかし半径を大小させると、丸ごと点滅するネオンではなく呼吸するように柔らかく光ります。親要素にposition:relativeとisolation:isolateがないと、この背後のレイヤーが舞台の背景色の下に完全に隠れてしまいます。ダークヒーローのバッジやライブ状態のタイトルに向いています。

filter:blur다색 그러데이션숨쉬는 글로우
.neon { position: relative; isolation: isolate; }
.neon::before {
  content: attr(data-text);
  position: absolute; inset: 0; z-index: -1;
  background: inherit;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: blur(4px);
  animation: breathe $duration $easing infinite;
}
@keyframes breathe {
  0%, 10%  { filter: blur(4px); opacity: .28; }
  15%, 25% { filter: blur(20px); opacity: 1; }
}

04光沢スイープ文字

単色の文字の上に同じ文言をもう一枚重ね、その層だけ細く明るい帯をbackground-clip:textで流し込み、background-positionで一方向に一度だけ走らせると金属に光が当たったように見えます。プレミアム会員バッジやVIP限定タイトルに向いています。

background-position 스윕대각선 하이라이트2s
.light {
  background: linear-gradient(100deg, transparent 42%, rgba($stage-paper, .95) 50%, transparent 58%);
  background-size: 260% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: sweep $duration $easing infinite;
}
@keyframes sweep {
  0%  { background-position: 140% 50%; }
  60% { background-position: -40% 50%; }
}

05グリッチ文字

色違いの2枚を重ね、横縞のmask-imageの位置をsteps()のタイミングで飛び飛びに動かしてスキャンラインを崩し、同じ瞬間にfilter:hue-rotateを一瞬跳ねさせて色をずらします。clip-pathで切って動かす方式ではなく、マスクの位置ジャンプだけでこの崩れを作っています。エラー・警告バナーのタイトルやメンテナンス案内に向いています。

mask-image steps()hue-rotate스캔라인
.r, .b {
  position: absolute; inset: 0;
  mix-blend-mode: screen;
  -webkit-mask-image: repeating-linear-gradient(to bottom, #000 0 3px, transparent 3px 7px);
  mask-image: repeating-linear-gradient(to bottom, #000 0 3px, transparent 3px 7px);
  animation: mask-jump-r $duration $easing infinite;
}
@keyframes mask-jump-r {
  0%, 40%, 100% { -webkit-mask-position: 0 0; mask-position: 0 0; opacity: 0; }
  45%, 55%      { -webkit-mask-position: 0 3px; mask-position: 0 3px; opacity: .9; }
}

06クロームメタル文字

濃色と白・クリーム色を細かいストップで交互に並べたグラデーションをbackground-clip:textで流し込み、background-positionをゆったり動かすと、クロームの表面を反射光が通り過ぎる質感になります。ゲーム・スポーツブランドのロゴタイプやタイトルロゴに向いています。

다중 스톱 그러데이션background-position2s · ease-out
.chrome {
  background: linear-gradient(
    100deg,
    $color 0%, $stage-paper 12%, $color 24%,
    $subject-cream 40%, $stage-paper 52%, $color 64%,
    $stage-paper 80%, $color 100%
  );
  background-size: 220% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: reflect $duration $easing infinite;
}

07点滅文字

文字をspanで一つずつ分け、--i変数で文字ごとに異なる遅延を与えてopacityを短く往復させます。ネオン1本が丸ごと消えて点くのではなく、古い電球マーキー看板のように文字ごとに別々に点滅します。劇場マーキー風タイトルやライブイベントバナーに向いています。

--i 지연opacity 왕복글자별 독립
.marquee span {
  display: inline-block;
  color: $color;
  animation: bulb $duration $easing infinite;
  animation-delay: calc(var(--i, 0) * 120ms);
}
@keyframes bulb {
  0%, 40%, 100% { opacity: 1; }
  47%           { opacity: .22; }
  54%           { opacity: 1; }
}

08アウトライングロー

color:transparentで中身を空にし-webkit-text-strokeで輪郭だけ残したうえで、filter:drop-shadow()の半径を大小させると、輪郭のまわりに光が呼吸するようににじみます。ダークモードCTAの見出しやカードバッジのアウトラインに向いています。

-webkit-text-strokedrop-shadow빈 윤곽선
.outline {
  color: transparent;
  -webkit-text-stroke: 2px $color;
  animation: glow $duration $easing infinite;
}
@keyframes glow {
  0%, 100% { filter: drop-shadow(0 0 3px rgba($color, .5)); }
  50% {
    filter: drop-shadow(0 0 14px rgba($color, .9))
            drop-shadow(0 0 26px rgba($color, .5));
  }
}

09虹色文字

固定した虹色の多色グラデーションをbackground-clip:textで流し込み、位置や角度ではなくfilter:hue-rotateを0degから360degへ回し続けると、色相環全体が巡回して見えます。遊び心のあるブランドロゴやフェス・イベントタイトルに向いています。

filter:hue-rotate고정 그러데이션360° 순환
.rainbow {
  background: linear-gradient(90deg, $color, $stage-yellow, $stage-orange, $error, $subject-cream, $color);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: hue-cycle $duration $easing infinite;
}
@keyframes hue-cycle {
  from { filter: hue-rotate(0deg); }
  to   { filter: hue-rotate(360deg); }
}

どこで壊れるか — 接頭辞とアイソレーション

01・02・03・04・05・06・09の七つが使うbackground-clip:textは、長らく接頭辞が必要だったプロパティです。caniuseのbackground-clip-text対応表によれば、Chrome・Edgeは120以降、Safariは15.5以降で接頭辞なしのまま動き、それより前のバージョンでは-webkit-background-clip:textがないと文字がグラデーションで塗られません。だからこの7本すべてで、接頭辞ありと接頭辞なしの宣言を並べて書いています。05が使うmask-imageも接頭辞つきの時期が長いプロパティで、接頭辞なしで動くのはChrome・Edgeが120以降、Safariが15.4以降、Firefoxが53以降です。だから05では-webkit-mask-imageと-webkit-mask-positionも接頭辞なしの宣言と並べて書いています。03のisolation:isolateは別の理由で必要です。後光のレイヤー(z-index:-1)が親の重なりの文脈からはみ出すと、舞台の背景色の下に完全に隠れてしまうため、isolation:isolateで新しい重なりの文脈をその場に作っています。

02の@propertyは対応の幅がさらに狭く、MDNの@propertyのページを見るとChrome・Edgeは85以降、Safariは16.4以降で使えるものの、Firefoxが正式に対応したのは128からです。@propertyがない古いブラウザでは角度の値が補間されないため、グラデーションは回転せず止まって見えますが、レイアウト自体は崩れません。実運用では静止した状態を基準に考え、回転はおまけとして扱うのが安全です。ここまで計測しながら直した9本のzipを開く合言葉は5hzhmkcbで、下のカードから取り出せます。

アクセシビリティ

9つともprefers-reduced-motion: reduceでアニメーションが止まりますが、要素そのものは消えません。背景位置を動かす01・04・06は帯の途中で止まり、02は角度が45degに固定されてグラデーションが回転しない状態で残ります。03の後光と08の輪郭グローは呼吸を止め、一定の柔らかさのまま光り続けます。05のグリッチは色ずれ用の2枚のレイヤーだけが消え、下地の一枚だけが静止した文字として残ります。07の点滅は全文字が同じ明るさで止まり、09の色相環はhue-rotate(0deg)に戻って固定され、虹色の多色グラデーションが巡回せず静止した状態で残ります。background-clip: textで文字の中身を透明にする効果は色弱や低彩度モニターだとコントラストが弱く見えることがあるので、実運用の見出しにはこの効果だけに頼らず近くに通常のテキストやアイコンも添えるのを勧めます。prefers-reduced-motion自体はMDNのドキュメントにまとまっています。

@media (prefers-reduced-motion: reduce) {
  .flow, .chrome { animation: none; background-position: 40% 50%; }
  .spin { animation: none; --angle: 45deg; }
  .neon::before { animation: none; filter: blur(10px); opacity: .85; }
  .light { animation: none; background-position: 50% 50%; }
  .r, .b { animation: none; opacity: 0; }
  .marquee span { animation: none; }
  .outline { animation: none; filter: drop-shadow(0 0 10px rgba($color, .7)); }
  .rainbow { animation: none; filter: hue-rotate(0deg); }
}

文字のグラデーションやシャイン以外のCSSアニメーションはCSSカテゴリー一覧に集めていて、このサイトが何を基準にデモを選んでいるかは紹介ページに書いています。

FAQ

グラデーション文字に-webkit-の接頭辞はまだ必要ですか?

訪問者の大半はすでにChrome 120・Safari 15.5以降を使っているため、接頭辞なしのbackground-clip: textだけでも十分です。ただし接頭辞を一緒に書くコストはほぼなく、古いブラウザでは接頭辞がないとグラデーションどころか文字ごと見えなくなることもあるので、background-clip: textを使う7本すべてに接頭辞を残しています。

09の虹色テキストは色覚特性のある人にどう見えますか?

色相環を巡回させる効果なので、特定の2色の区別が難しい人にも「色が変わり続けている」こと自体は伝わります。ただし色の違いで成功・失敗のような意味を伝える用途には使わず、装飾的なタイトルだけに使うことを勧めます。

9つを1つの見出しに重ねて使ってもいいですか?

技術的には可能ですが勧めません。background-clip: textとfilter: blur()・mask-imageを同時に何層も重ねると、ブラウザが毎フレーム描き直すレイヤーが増え、非力なモバイル端末ではまずカクつきが目立ちます。見出し1つには9つのうち1つだけを選ぶことを勧めます。

解凍パスワードを入力してください

パスワードはこの記事の本文の中にあります。読み進めると出てきます。