Menu

CSS transition の使い方: プロパティ、時間、イージング、遅延

CSS の transition は、ホバーなどでプロパティが変わったとき、古い値から新しい値へアニメーションさせます。transition のショートハンド、すべてのタイミング関数の比較、変化させられるものとできないもの、height: auto の回避策、動きを減らす設定を解説します。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

transition を 1 つの例で

transition はブラウザに「このプロパティが変わったら、すぐに切り替えずにこれだけの時間をかけてアニメーションさせて」と伝えます。:hover だけでなく、要素の通常のルールに書きます:

1 つ目のボタンにホバーすると、0.4 秒かけて色が緑に変わり、4px 浮き上がります。ポインターを離すと、同じ transition が逆向きに再生されます。2 つ目のボタンは transition: none なので、すぐに切り替わります。キーボードで操作する人には :focus-visible で同じ効果が届きます。

transition のショートハンド

transition: background-color 0.3s ease-in-out 0.1s;
/*          property         duration timing    delay */
個別のプロパティ指定するもの初期値
transition-propertyアニメーションさせるプロパティ (all かリスト)all
transition-durationかける時間 (s か ms)0s
transition-timing-function速さの曲線ease
transition-delay始まるまでの待ち時間 (負の値も可)0s

duration の初期値は 0s なので、指定するまで何もアニメーションしません。ショートハンドでは、1 つ目の時間が常に duration、2 つ目が delay です。プロパティごとに設定を変えるなら、カンマで区切ります:

.card {
  transition: transform 0.2s ease-out, box-shadow 0.4s ease-out;
}

タイミング関数の比較

タイミング関数は、transition の間に速さがどう変わるかを決めます。Play を押すと、7 本のバーがすべて同じ 1.5 秒で同じ距離を動きます:

タイミング関数印象
linear一定の速さ。機械的
ease (初期値)すばやく始まり、ゆっくり止まる
ease-inゆっくり始まり、速く終わる。去っていくものに向く
ease-out速く始まり、ゆっくり終わる。入ってくるものに向く
ease-in-out両端がゆっくり
cubic-bezier(x1, y1, x2, y2)自分で決めた曲線。y が 1 を超えると行き過ぎてから戻る
steps(n)途中のフレームなしで、n 回の等しい段階で飛ぶ

ホバーの効果やメニューには、150ms から 300ms の ease-out が反応よく感じられます。

transition できるもの

途中の値があるプロパティは transition できます。色、長さ (width、padding、margin)、opacity、transform、box-shadow、border-radius、filter、background-color などです。display や font-family のようにキーワードの間で切り替わるプロパティは、すぐに切り替わります。

一番よくつまずくのが height: auto です。height: 0 から height: auto に開くパネルは、初期状態ではアニメーションしません。ブラウザは 0 と「auto」の間の値を計算しないからです。確実な回避策は、1 行だけの grid のラッパーで行を 0fr から 1fr にすることです:

aria-expanded はスクリーンリーダーの利用者に、パネルが開いているかどうかを伝えます。アニメーションだけでは伝わりません。

transition の終了時にコードを実行する

transitionend イベントは、transition が終わったときにプロパティごとに 1 回発生します。フォーカスを移す、要素を取り除くなど、動きの後に何かをするときに使います:

動きを減らす設定を尊重する

画面上の動きでめまいがしたり気が散ったりするため、システムの設定で「視差効果を減らす」をオンにしている人がいます。メディアクエリを使って、色や opacity のフェードは残し、大きな動きはやめましょう:

@media (prefers-reduced-motion: reduce) {
  .btn { transition: background-color 0.2s ease; } /* no movement, only the color */
}

transition をなめらかに保つ

transform と opacity は一番負荷の軽いアニメーションのプロパティです。ブラウザはレイアウトを計算し直さずに、要素を動かしたりフェードさせたりできます。width、height、top、margin を transition させると、ブラウザは毎フレームページを配置し直すので、遅いスマートフォンではカクつくことがあります。何かを動かすなら、left や margin より transform: translate() を使いましょう。関数は transform のページ で解説しています。

よくある間違い

  • transition を :hover のルールにだけ書く。 アニメーションで入りますが、ホバーが終わるとすぐに戻ります。transition は基本のルールに書きましょう。
  • 時間に単位がない。 transition: opacity 300 は無効です。300ms か 0.3s と書きます。
  • transition: all。 変わるプロパティをすべてアニメーションさせるので、意図しないものまで動き、レイアウトの変化が重くなることがあります。プロパティを列挙しましょう。
  • display: none でフェードすると思う。 display はすぐに切り替わります。代わりに opacity をフェードさせましょう (フェードが終わったら visibility: hidden にします)。
  • height: auto へ transition させる。 飛んでしまいます。上の grid-template-rows のテクニックを使いましょう。
  • 小さな操作に長い時間をかける。 ボタンやメニューで約 400ms を超えると遅く感じます。

よくある質問

CSS の transition はどう動きますか?

要素に、どのプロパティをどれくらいの時間でアニメーションさせるかを宣言します。例: transition: background-color 0.3s ease;。そのプロパティの値が (:hover、クラス、JavaScript で) 変わると、ブラウザはすぐに切り替えずに古い値から新しい値へアニメーションさせます。

transition のショートハンドの値の順番は?

transition: property duration timing-function delay; です。例: transition: opacity 0.3s ease-in 0.1s;。厳密なルールは、1 つ目の時間が duration、2 つ目が delay ということだけです。複数の transition はカンマで区切ります。

CSS の transition が効かないのはなぜですか?

よくある原因は、transition が :hover のルールにしかない (アニメーションで入ってすぐ戻る)、アニメーションできないプロパティ (display、auto への height)、時間に単位がない (0.3s ではなく 0.3)、要素がページに追加されたのと同じ瞬間に値が変わる、のいずれかです。

height: auto に transition できますか?

すべてのブラウザで普通の height の transition ではできません。auto への補間には新しい interpolate-size プロパティが必要で、まだどこでも使えるわけではありません。よくある回避策は、grid のラッパーで grid-template-rows を 0fr から 1fr にアニメーションさせるか、max-height を内容より大きい値までアニメーションさせることです。

CSS の transition と animation の違いは何ですか?

transition は、プロパティが変わったときに 2 つの値の間で 1 回だけ動きます。animation は @keyframes を使い、たくさんの段階を持てて、ページの読み込み時に自分で始まり、繰り返しやループもできます。

Coddy programming languages illustration

Coddyでコードを学ぼう

始める