Loading

ROUTE

ルートゼロの
アクティビティ

CSS文字アニメーションの作り方|フェード・1文字ずつ・タイピング

1

CSSで文字を動かす方法は1つではありません。ふわっと表示するのか、1文字ずつ見せるのか、タイピングのように横へ広げるのかで実装が変わります。まず目的を分けると、必要なCSSがかなりシンプルになります。

まず使い分け:文字アニメーションは目的で選ぶ

見せ方 主なCSS 向いている場面
フェード opacity + @keyframes 見出しや短いコピーを自然に表示
1文字ずつ span + animation-delay ロゴや短いキャッチコピー
タイピング風 width + steps() 固定長の短いテキストを段階表示

動的に変わる長文や、ユーザー操作に応じて複雑に順序を変える場合は、CSSだけに寄せずJavaScript側で状態を管理した方が保守しやすいことがあります。

(@keyframesとanimationの基本から確認したい場合については『【簡単に試せる】CSSアニメーションの仕組みを徹底解説!初心者でもわかる動きの作り方』をご参照ください)


フェード表示はopacityと@keyframesで作る

最も扱いやすいのは、透明度を変えるフェードです。@keyframesで開始と終了の状態を定義し、対象要素へanimationを指定します。

<p class="fade-text">CSSで文字を表示する</p>

<style>
.fade-text {
  opacity: 0;
  animation: fade-in 700ms ease-out forwards;
}

@keyframes fade-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
</style>

forwardsを付けると、アニメーション終了後も最終キーフレームの見た目を維持できます。繰り返しが不要な文章では、まず1回だけの表示から始めると調整しやすくなります。


1文字ずつ表示するなら文字を要素へ分けて遅延させる

各文字の開始時刻をずらしたい場合は、文字ごとにspanへ分けてanimation-delayを変えます。固定コピーならCSSだけでも管理できます。

<p class="char-text" aria-label="HELLO">
  <span class="char" aria-hidden="true">H</span>
  <span class="char" aria-hidden="true">E</span>
  <span class="char" aria-hidden="true">L</span>
  <span class="char" aria-hidden="true">L</span>
  <span class="char" aria-hidden="true">O</span>
</p>

<style>
.char {
  display: inline-block;
  opacity: 0;
  animation: char-in 400ms ease-out forwards;
}
.char:nth-child(2) { animation-delay: 80ms; }
.char:nth-child(3) { animation-delay: 160ms; }
.char:nth-child(4) { animation-delay: 240ms; }
.char:nth-child(5) { animation-delay: 320ms; }

@keyframes char-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}
</style>

文字数が頻繁に変わる場合、nth-childを手で増やし続けるのは負担です。その場合は、JavaScriptやテンプレート側で文字要素と遅延値を生成する方が向いています。


タイピング風はsteps()で段階的に幅を広げる

steps()は、アニメーション進行を指定した数の区間に分割します。幅の変化と組み合わせると、文字が段階的に現れるタイピング風表現を作れます。

<p class="typing">CSS animation</p>

<style>
.typing {
  width: 13ch;
  overflow: hidden;
  white-space: nowrap;
  border-right: 2px solid currentColor;
  animation:
    typing 2s steps(13, end) forwards,
    caret 700ms step-end infinite;
}

@keyframes typing {
  from { width: 0; }
  to { width: 13ch; }
}

@keyframes caret {
  50% { border-color: transparent; }
}
</style>

この方法は固定文字列ほど扱いやすく、文字数とsteps()の値、幅の指定をそろえる必要があります。フォントや文字種によって見え方が変わるため、実際の表示環境で確認してください。

動きを減らす設定を用意する

文字の移動や点滅は、利用者によっては負担になります。prefers-reduced-motionで動きの抑制を希望している場合は、必須ではないアニメーションを停止または弱める設計ができます。

@media (prefers-reduced-motion: reduce) {
  .fade-text,
  .char,
  .typing {
    animation: none;
    opacity: 1;
    transform: none;
    width: auto;
    border-right: 0;
  }
}

アニメーションそのものが情報伝達に必須でないなら、動かない状態でも内容を読めることを優先します。

CSSだけで足りないケースを見分ける

  • 文字列がAPI結果などで毎回変わる
  • ユーザー操作で再生・停止・順序を細かく制御する
  • 複数要素の状態を同期させる
  • アニメーション完了を次の処理条件として使う

このような場合はJavaScriptで状態を持ち、CSSは見た目の変化を担当させると責務を分けやすくなります。

(ほかのCSSアニメーション実装例も確認したい場合については『【保存版】Web制作で使えるCSSアニメーション10選|サンプルコード&使い方解説』をご参照ください)

(スクロール位置と連動させたい場合については『CSSスクロールアニメーション完全解説|scroll-timelineでJS不要の軽量演出を実現』をご参照ください)

まとめ:まず見せ方を決めてからCSSを選ぶ

  • 自然に出すならopacity中心のフェード
  • 短い固定コピーなら文字ごとのdelay
  • タイピング風ならsteps()と幅の組み合わせ
  • 動的制御が増えたらJavaScriptへ役割を分ける
  • prefers-reduced-motionで動きを減らせるようにする

まずは短い見出し1つでフェードを動かし、次に1文字ずつ・タイピング風へ広げると違いを確認しやすくなります。

カジュアル面談はこちら

RANKINGranking-icon

すべてを開示している会社です

ポジティブな面もネガティブな面も、包み隠さず誠実にお答えします。
気になることがあれば、面談の際にすべてオープンにお話します。