動きの基本
決めることは2つだけです。どれだけの時間で動くか、その時間をどう配分するか。等速で動くものは、現実にはほとんどありません。
図の中身を文字で読む
- イージング=時間に対する進み方。縦軸が進行度、横軸が時間。
- linear
- 等速
- 機械的に見える
- 回転する読込表示だけ
- ease-out
- 速く出て、ゆっくり止まる
- 画面に入るとき
- 迷ったらこれ
- ease-in
- ゆっくり出て、速く去る
- 画面から出るとき
- 入りに使うと鈍く感じる
- spring
- 行き過ぎて戻る
- 指で動かした物の慣性
- 時間ではなく物理で決まる
- cubic-bezier
- 2つの制御点で曲線を作る
- .17,.67,.34,1 の4つの値がこの2点の座標
- 所要時間の目安(動く距離が長いほど長く)
- 100ms 色や不透明度の変化。押した手応え
- 200〜300ms 開閉、切り替え、要素の出入り。ここが基準
- 400〜500ms 画面全体が動くとき。これを超えると待たされていると感じる
ひと目で#
決めることは2つだけ。どれだけの時間で動くか(デュレーション)と、その時間をどう配分するか(イージング)。
- トランジション
- 状態Aから状態Bへ。始まるきっかけが要る
- アニメーション
- キーフレームで途中の状態も指定する。繰り返せる
- イージング
- 進み方の曲線。等速で動くものは現実にほとんどない
- キュービックベジェ
- 曲線を2つの制御点の座標で表したもの
- スプリングアニメーション
- 時間ではなく、質量とばね定数で決まる動き
- モーショントークン
- 時間とイージングに名前を付けて共有する
使い分け#
| こういうとき | 使うもの |
|---|---|
| hover や開閉で状態が変わる | トランジション |
| 途中の状態を指定したい。繰り返したい | アニメーション(キーフレーム) |
| 画面に入る | ease-out |
| 画面から出る | ease-in。入りより短く |
| 位置が移る | ease-in-out |
| 読み込み中の回転 | linear |
| 指で動かしたものが止まる | スプリング |
入りと出は同じにしない#
入るものは丁寧に見せ、出るものはすばやく引きます。閉じたパネルは用済みなので、消え際を見せる意味がありません。時間は半分、曲線は逆にします。
図の中身を文字で読む
- ✕ 入りの設定を出にも使い回す ○ 出は短く、逆の曲線で
- 閉じるときも同じ時間をかけて、ゆっくり止まる 入りは丁寧に見せて、出はすばやく引く
- 入り 240ms・ease-out 入り 240ms・ease-out
- 240ms・ease-out のまま 120ms・ease-in
- 出 出
- 消えるのを待たされる すっと引いて、操作の邪魔をしない
- トークンにすると
- 入り = --dur-base 240ms + --ease-out(速く出て、ゆっくり止まる)
- 出 = --dur-fast 120ms + --ease-in(ゆっくり出て、速く去る)
同じ --dur-base と --ease-out を出入りの両方に当てると、閉じるボタンを押したあと0.24秒、画面が固まったように見えます。押した手応えを返すだけの色の変化なら、さらに短く120msで足ります。
間違えやすいところ#
- 全部に同じ時間を割り当てる移動の距離が長いほど、時間は長く要る
- 出るときも ease-out にする消えるのを待たされる
- 500ms を超える動きを操作の途中に置く操作が遅いと感じられる
allを対象にする想定しない値まで補間され、性能も落ちる。プロパティを指定するdisplay: noneへ transition をかける補間できない。opacityと組み合わせる- 時間とイージングをあちこちに直書きする揃いが崩れる。トークンにする
直す例#
架空の案件を1つ例にとります。どこを見て、何をどう直すかを書きます。
工務店サイトの絞り込みパネルです。開くのも閉じるのも all 300ms linear の1行で書かれています。開くところだけ見ると悪くありません。問題は閉じたときで、押してから0.3秒、パネルが等速で薄くなっていく間、下の一覧に手が届きません。
直すのは2か所です。入りは240msの --ease-out のまま、出は120msの --ease-in に分けます。もう1つ、all をやめて opacity と transform だけを名指しします。all のままだと、パネルの高さや影まで補間の対象に入り、閉じるたびにレイアウトの計算が走ります。
対象を絞って出入りを分けるだけで、「重い」という指摘は消えます。時間を短くするより先に、この2つを見ます。
確認する#
- 閉じる動きが、開く動きより短い(同じ変数を出入りの両方に当てていない)
transitionの対象がプロパティ名で書かれている(allが残っていない)- 時間とイージングが
:rootの変数から来ている(部品側に ms の直書きが無い)
使えるパターン#
このページで扱う語#
このページで扱う語を並べる本文では太字3 語
語の名前から引くなら用語索引へ。
- デュレーション
- 動きが始まってから終わるまでの時間。長さによって印象と体感速度が変わる。
- キーフレーム
- アニメーションの途中で、状態を明示的に指定する時点。その間は自動的に補間される。
- 補間
- 指定された2点の間の値を計算で埋めること。
この話が要る場面#
このページが答えになる、現場の困り事です。困り事の側から探すと、同じ場所に着きます。
画面に入るのは ease-out、出るのは ease-in で入りより短く。開閉や切り替えは200〜300ms。
このコードで動いている見本です
移動距離に比例させる。距離が変わらないのに時間だけ長くすると、待たされていると感じる。
このコードで動いている見本です
状態が変わるきっかけがあるならトランジション。途中を指定したい、繰り返したいならアニメーション。
このコードで動いている見本です
display: none に transition が効かない
display は補間できない。opacity と visibility を組み合わせるか、@starting-style を使う。
このコードで動いている見本です
この場面のほかの困り事と、そのまま貼れる部品は動かすにまとめてある。逆引きには全188件。
イージングを試す#
この値は作業台で決められます。和文の予約ページに載せて、幅と明暗を替えて確かめてから CSS を持ち帰る: 動きの曲線と時間
8種類と自分で描いた1本を同時に動かして見比べます。左から右へ走り、1秒おいて左端へ戻ります。曲線と時間を決めて生成すると、動きを減らす設定への対応まで含んだ CSS が出ます。
行を押すと、その曲線だけが動いて採用されます。いちばん下の「自分で描く」は、右の曲線の点を掴んで動かせます。
曲線の編集。2つの点を掴んで動かします。薄い帯の外は 0〜1 の外(行き過ぎて戻る)で、上下に 1 ぶんずつ余白があります。
もっと細かく(場面ごとの時間・距離・ずらし・URL に残す)は作業台の「動きの曲線と時間」で。
/* 採用: 急停止 cubic-bezier(0.16, 1, 0.3, 1)
素早く出て静かに止まります。UIの入りに向きます */
:root {
--dur-fast: 120ms; /* 色の変化と、出るとき */
--dur-base: 240ms; /* 開閉と、入るとき */
--ease-out: cubic-bezier(0.16, 1, 0.3, 1);
--ease-in: cubic-bezier(0.7, 0, 0.84, 0);
}
.panel { transition: opacity var(--dur-base) var(--ease-out),
transform var(--dur-base) var(--ease-out); }
.panel[hidden] {
display: block; /* hidden の display: none を打ち消す。
打ち消さないと補間そのものが起きない */
opacity: 0;
transform: translateY(8px);
pointer-events: none;
transition-duration: var(--dur-fast);
transition-timing-function: var(--ease-in);
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
この道具は JavaScript で動きます。無効の場合は、上の表と既定値のコードを使ってください。