Skip to content
This page has been auto-translated and may contain errors.View in English

トランジションとアニメーション

docs.scrimba.com

ボタンに:hover色を加えて動作しますが、変化は急激です。1フレームは青で、次のフレームは暗くなり、その間には何もありません。わずかなフェードがあれば、ページ全体がジャンプして見えなくなります。そのフェードはトランジションであり、2つの状態間のモーションを記述できれば、同じツールはホバー効果、持ち上がるカード、そして何かが読み込まれている間に回転するスピナーにスケールアップします。この章は、CSSがどのようにものを動かすか、そしてページを使いにくくしないように動かす方法についてです。

トランジション

**トランジション**は、プロパティを古い値から新しい値にアニメートするのではなく、その間をスナップするのではなく、スナップするのではなく、アニメートするようにブラウザに指示します。通常の状態とホバー状態の2つの状態を記述し、トランジションがその間のフレームを埋めます。

ホバー時に色が変わるボタンです。トランジションなしでは色がジャンプします。あれば色がフェードします。

css
.btn {
  background: #3b82f6;
  transition: background 0.2s;   /* 0.2秒かけて色をフェード */
}
.btn:hover {
  background: #1d4ed8;           /* アニメートする新しい状態 */
}

transition:hoverではなく通常の状態に置きます。そうすることで、マウスが到着したときと離れたときの両方に適用されます。

**トランジション**は、その値が変わるたびにプロパティを2つの値の間でアニメートします。通常は:hover:focusなどの状態が開始されたり、クラスが追加されたりします。アニメーションをフレームバイフレームで記述するのではなく、プロパティと期間を名付けると、ブラウザはその間の値を補間します。

transitionの短縮形には、この順序で4つの部分があります。監視するプロパティ、期間、タイミング関数(速度曲線)、およびオプションの遅延。

css
.btn {
  background: #3b82f6;
  transition: background 0.2s ease-in-out 0s;
  /* プロパティ | 期間 | タイミング関数 | 遅延 */
}
.btn:hover {
  background: #1d4ed8;
}

複数のプロパティを同時にトランジションできます。コンマで区切ることで、トランジションをベース状態で宣言してホバーの開始と終了をカバーします。

css
.card {
  transition: transform 0.2s, box-shadow 0.2s;   /* 2つのプロパティ、同じタイミング */
}

**トランジション**は、計算値が変わるたびに、時間をかけてプロパティを開始値から終了値に補間します。トリガーはそのプロパティへの変更です。:hoverなどの疑似クラス、JavaScriptから切り替えられるクラス、またはインラインスタイルの編集。4つのサブプロパティはtransition-propertytransition-durationtransition-timing-function、およびtransition-delayです。短縮形はプロパティ、期間、タイミング、遅延の順です。

トランジションが実行されるかどうかを決定する2つの制約があります。プロパティはアニメート可能である必要があります。これは、2つの値の間に定義された補間があることを意味します。background-coloropacity、およびtransformはそうですが、displayなどのプロパティは個別で歴史的にトゥイーンするのではなくスナップします。また、開始値と終了値の両方が具体的である必要があります。autoへの/から遷移することはできません。これがheightautoにアニメートしても何もしない理由で、max-heightまたはtransformに到達します。

css
.btn {
  background: #3b82f6;
  transition: background-color 0.2s ease-in-out;   /* アニメート可能、両方の値が具体的 */
}
.btn:hover {
  background: #1d4ed8;
}

:hoverルールではなく、ベースルールでトランジションを宣言します。有効なトランジションプロパティは要素の現在の状態から読み込まれるため、ベース状態に配置することは到着と戻りの両方を制御することを意味します。:hoverにのみ配置すると、入った方法がアニメートされ、出た方法がスナップされます。

JunoTransitions トランジションはスナップするのではなく変更をスムーズにします。ホバー時にボタンの色をフェードするなど。通常の状態に書き込みます。:hoverではなく、入ったり出たりする両方の方法で動作します。propertydurationで開始すれば、既に機能するフェードがあります。
JunoTransitionstransition短縮形はプロパティ、期間、タイミング関数、遅延を読み込み、複数をコンマで区切ることでリストアップします。ベースルールに配置して、状態の開始と終了をカバーします。ホバーが入ったときはスムーズに見え、出たときはジャンプする場合、トランジションは:hoverではなくベースにあります。これは頻繁に人々を引き止めます。
JunoTransitions トランジションは2つの具体的な終了値を持つアニメート可能なプロパティでのみ実行されます。これがheight: autoへの遷移が静かに何もしない理由です。ベース状態で宣言を保つため、スナップするのではなく両方の方向で制御されます。4つのサブプロパティを知ったら、短縮形は単にその順序です。プロパティ、期間、タイミング、遅延。

トランスフォーム

**transform**は、要素を周囲に邪魔することなく、移動、スケール、または回転させます。アニメートする場合、スムーズに見えて隣人を押し出さないため、通常は必要です。

常に到達する3つがあります。

css
.card:hover {
  transform: translateY(-4px);   /* 4ピクセル上に移動 */
}
.icon:hover {
  transform: scale(1.1);         /* サイズの110%に成長 */
}
.arrow.open {
  transform: rotate(90deg);      /* 時計方向に4分の1回転 */
}

translateは移動し、scaleはサイズを変更し、rotateは回転させます。これらのいずれかをトランジションと組み合わせると、持ち上がるカード、ポップするアイコン、またはスイングするアローが得られます。

transformは要素に視覚的な変更を適用し、サイズを変更したり、回転させたり、レイアウトでの場所を変更せずにサイズを変更します。最後の部分がポイントです。トランスフォームされた要素は新しい位置で描画されますが、元の占有スペースは予約されたままであるため、隣人は反射しません。これが、topまたはmarginではなくtransformを移動のためにアニメートする理由です。

最も使用する3つはtranslate()scale()、およびrotate()です。これらを1つの宣言で組み合わせることができます。

css
.card {
  transition: transform 0.2s ease-out;
}
.card:hover {
  transform: translateY(-4px) scale(1.02);   /* リフトと軽く成長 */
}

関数は左から右に適用され、transform-originはそれらが回転する点を設定し、デフォルトは要素の中心です。top leftに変更すると、rotateはコーナーから振られます。

css
.badge {
  transform-origin: top left;
  transform: rotate(-8deg);
}

transformは、ドキュメントフローに影響を与えずに、独自の塗装レイヤー内の要素を再配置します。ボックスの元の空間は予約されたままであるため、トランスフォームが変更されたときに兄弟が反射せず、レイアウトが再計算されません。そのプロパティはtransformをアニメートする正しいことを作ります。下のパフォーマンスに関するDeep Diveがポイントを正確にします。

translate()scale()、およびrotate()は一般的な関数であり、順序は重要です。これは右から左へ効果的に適用される行列乗算として構成するため。translateX(50px) rotate(45deg)は移動されてから要素を回転させますが、逆は最初に回転し、次に回転軸に沿って変換され、異なる結果を与えます。transform-originscalerotateのピボットを設定し、要素の中心(50% 50%)にデフォルトします。

css
.panel {
  transform-origin: top center;
  transition: transform 0.25s ease-out;
}
.panel.collapsed {
  transform: scaleY(0);          /* 上辺に向かって折りたたむ */
}

1つの実用的な制約:transformは、この方法で配置できるボックスを生成する要素にのみ適用されるため、<span>のようなベアインライン要素には影響しません。要素を最初にdisplay: inline-blockまたはblockに与えます。要素を配置している場合は、トランスフォームが配置コンテキストとどのように相互作用するかに注意してください。トランスフォームされた要素は絶対配置された子孫のための含有ブロックになります。

JunoTransformstransformは、隣人を押し出さずに要素を移動、スケール、または回転させます。覚える3つはtranslate(移動)、scale(サイズ変更)、およびrotate(回転)です。トランジションと組み合わせると、ホバー時に持ち上がるカードやポップするアイコンが得られます。
JunoTransformstransformは、レイアウト内での位置を変更せずに要素の見た目を変更するため、隣人が反射することはなく、topまたはmarginではなく、アニメートすることができます。1つの宣言でtranslatescale、およびrotateをスタックし、左から右に適用されます。transform-originに到達して、中心以外の場所で回転またはスケールのピボットが必要な場合。
JunoTransforms トランスフォーム関数は順序で構成されるため、translateX(50px) rotate(45deg)は逆ではなく、transform-originは回転またはスケールが回転する内容を設定します。ベアインライン要素では何もしないまで、inline-blockにしてください。また、要素が絶対配置された子供のための含有ブロックになることにも注意してください。これは後で驚くかもしれません。

キーフレームアニメーション

トランジションは2つの状態間でアニメートします。2つ以上が必要な場合、またはモーションが繰り返す必要がある場合は、**キーフレームアニメーション**を使用します。@keyframesでステップを書き出し、animationプロパティを使用して要素にアタッチします。

ローディングスピナーは古典的な例です。永遠に回転するため、トランジションはそれを実行できません。

css
@keyframes spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
.spinner {
  animation: spin 1s linear infinite;   /* spinを実行、1s/ターン、永遠に */
}

fromは開始であり、toは終了です。animation行は、実行するキーフレーム、1サイクルの所要時間、速度曲線、および繰り返す回数を指定します。infiniteは永遠に止まらないことを意味します。

@keyframesは名前付きステップのシーケンスを定義し、animationプロパティはそれを要素で実行します。トランジションとは異なり、アニメーションはトリガーするために状態変化を必要としません。それは自分で開始し、0%から100%へのパーセンテージを使用して、必要なだけ多くのステップを持つことができます。

css
@keyframes pulse {
  0%   { transform: scale(1); }
  50%  { transform: scale(1.05); }   /* 中点ステップ */
  100% { transform: scale(1); }
}
.badge {
  animation: pulse 1.5s ease-in-out infinite;
}

animation短縮形は、いくつかのサブプロパティをバンドルします。名前、期間、タイミング関数、遅延、反復回数、および方向。infiniteは永遠にループし、数字はその回数実行し、方向としてalternateは各サイクルを逆にして、モーションが開始にジャンプするのではなく前後に実行されます。

css
.spinner {
  animation: spin 1s linear infinite;
}

@keyframesは、パーセンテージ(fromto0%100%のエイリアス)として表現されたポイントでのプロパティ値の名前付きタイムラインを宣言し、animationはそのタイムラインを要素にバインドします。アニメーションは自己トリガーであり、ループできます。これはトランジションとの行間です。トランジションを使用して状態変化をスムーズにし、独自に実行されたり繰り返されたりするモーションのためのアニメーションを使用します。

animation短縮形は8つのサブプロパティを実行します。animation-name-duration-timing-function-delay-iteration-count-direction-fill-mode、および-play-state。2つは人々を引き止めます。animation-fill-mode: forwardsは、アニメーションが終了した後に要素をその最終的なキーフレームに保つようにします。その代わりに、アニメートされていないスタイルに戻るのではなく、1回限りの入場に必要なものです。そしてタイミング関数は全体のアニメーション全体ではなく、キーフレームセグメントごとに適用されるため、3ステップアニメーション上のease-in-outは、各セグメントに出入りします。最後に最後に。

css
@keyframes slide-in {
  from { opacity: 0; transform: translateX(-16px); }
  to   { opacity: 1; transform: translateX(0); }
}
.toast {
  animation: slide-in 0.3s ease-out forwards;   /* 終了状態を保持 */
}

キーフレーム内のtransformopacityをアニメートすることを好みます。同じ理由でトランジションが次のセクションを展開します。これら2つのプロパティはアニメートするのが安いため、ほとんどのものはそうではありません。

JunoKeyframe animations 2つの状態で十分ではない場合、またはモーションが繰り返す必要がある場合は、@keyframesでステップを書き出し、animationで実行します。スピナーは頼りになる例です。0度でfrom、360でtoinfiniteでループ。animation行は、どのキーフレーム、どのくらい、曲線、および何回を設定します。
JunoKeyframe animations@keyframesはパーセンテージでステップを保持し、animationはそれを実行します。状態変化は不要です。短縮形は名前、期間、タイミング、遅延、反復回数、および方向を詰めているため、infiniteループし、alternateは各サイクルが前後に実行されます。マルチステップモーションと何かが繰り返されるのは、ここに属しており、トランジションではありません。
JunoKeyframe animations タイミング関数は全体のアニメーション全体ではなく、キーフレームセグメントごとに実行されます。これは、最初に簡潔にされたマルチステップランプがゴツゴツに見える場合、人々を驚かします。1回限りの入場が終了状態を保つはずの場合は、animation-fill-mode: forwardsに到達します。スナップバックではなく。そして、次の理由でパフォーマンス上の理由により、キーフレームをtransformopacityに保つようにしてください。

ユーザーを尊重するモーション

すべての人が画面上のモーションを望んでいるわけではありません。それを気を散らしやすい人もいて、他の人にとっては、それは本当の不快感や悪心を引き起こす可能性があります。ブラウザは、人々がシステム設定でそれを求めるようにしてくださいます。CSSは**prefers-reduced-motion**でその要求を読むことができます。

アニメーションをチェックでラップして、モーションを減らすようにお願いしていない人のためだけに実行されるようにします。

css
@media (prefers-reduced-motion: no-preference) {
  .card {
    transition: transform 0.2s;
  }
}

ユーザーを尊重する他の半分は抑制です。モーションは短く、微妙で、ホバーやクリックのようなリーダーがやったことに結び付けます。モーションは実際の変化に注意を向けることを支援します。それ自体のためのモーションは速く疲れます。

モーションは中立ではありません。読者の中には、アニメーションは気を散らすものであり、前庭障害を持つ人々のために、大きなまたは突然のモーションは、めまいや悪心を引き起こす可能性があります。オペレーティングシステムは「モーション削減」設定を公開し、prefers-reduced-motionメディア機能により、CSSは尊重できます。

モーションをオプトアウトではなく、オプトインとして扱います。落ち着いたベースラインをデフォルトとして作成し、no-preferenceクエリ内にモーションをレイヤーします。

css
.card {
  transition: none;              /* すべての人のための穏やかなデフォルト */
}
@media (prefers-reduced-motion: no-preference) {
  .card {
    transition: transform 0.2s ease-out;
  }
}

メディアクエリを超えて、目的は良いモーションをノイズから分離します。モーションはそれが説明する変化を説明するときに場所を獲得します。アンカーされたエッジからスライドするメニュー、それがどこからでも表示されないようにフェードするトースト。速く微妙に読むはポーランド語。遅く大きく読むと障害になります。

prefers-reduced-motionは、読者がOS レベルで選択したアクセシビリティ設定を反映するメディア機能であり、それを尊重することはニッチではなく、基本的な要件です。未来のモーションは前庭の不快感を引き起こす可能性があるため。到達するパターンは、削減状態をデフォルトとして作成し、@media (prefers-reduced-motion: no-preference)内にモーションを有効にすることです。読者のブラウザが機能をサポートしていない場合、穏やかなベースラインのではなく、モーションのムーションになります。

「削減」はめったに「削除」を意味しません。フェードまたは色の変更は通常、スライドまたはスケールではない場合に問題ありませんが、便利な移動は大きな位置モーションを小さな不透明度の変更に置き換えるのではなく、すべてのフィードバックをキルするのではなく。

css
.modal {
  animation: slide-in 0.3s ease-out;
}
@media (prefers-reduced-motion: reduce) {
  .modal {
    animation: fade-in 0.3s ease-out;   /* フィードバック、ドロップモーション */
  }
}

目的とイージング。他の重いことを実行します。入場はease-outを最もよく読みます。高速で始まり、落ち着きます。要素は意図で到着し、休息に来ます。出口は頻繁にease-inスーツです。期間を短く保つ(インターフェースフィードバックの約150msから300ms)とモーション小さい。一般的な失敗は、すべての相互作用に4分の1秒の待機を追加する素敵なアニメーションです。モーションは状態変化を説明する必要があり、1つを装飾しません。

JunoMotion that respects the user モーションを気を散らしやすい、あるいは身体的に不快な人もいます。彼らはそれを減らすことをブラウザに要求でき、prefers-reduced-motionでそれを読んで、モーションを減らさないように求めている人のためだけにアニメーションを実行します。追加するモーションは短く、微妙で、リーダーがやったことに結び付けます。
JunoMotion that respects the user 落ち着いたバージョンをデフォルトとして作成し、no-preferenceクエリ内でモーションを追加して、モーションはオプトインであり、人々が戦わなければならないものではなく、メニューがそれをアンカーから滑らせるなど、モーションのない変化。装飾のためのモーション。高速で小さく読むはポーランド語、遅く大きく読むと障害になります。
JunoMotion that respects the user 削減はめったに削除を意味しません。スライドをフェードに置き換えて、モーション削減を求めた人々がフィードバックを取得し、サポートされていないブラウザがそこに着陸するようにデフォルトを落ち着いた状態にします。入場にease-outを使用し、インターフェースフィードバックを150〜300ミリ秒に保ちます。待機時間をすべてのクリックに追加する素敵なアニメーションは機能ではなく、コストです。

アニメートするもの、そしてそれが重要な理由

後で問題を節約するルール:モーションをアニメートするとき、widthheighttop、またはmarginなどのプロパティではなく、transformopacityをアニメートします。

css
/* スムーズ:ブラウザはこれらを安く処理します */
.card:hover {
  transform: translateY(-4px);
  opacity: 0.9;
}

理由は、transformopacityが、ブラウザが最も安く周りに移動できる2つのプロパティであるため、それらの上に構築されたアニメーションは低速デバイスでもスムーズなままです。サイズまたは位置プロパティをアニメートすると、ブラウザはすべてのフレームでより多くの作業を行い、モーションはスタッター可能性があります。完全な理由に進むときに会うが、習慣は今構築する価値があります。

この章の例がtransformopacityに傾く理由があります。これら2つのプロパティは、アニメートするのが最も安いことであり、ほとんどのものはそうではありません。widthheighttop、またはmarginをアニメートすると、ブラウザはすべてのフレームでレイアウトを再計算するように強制され、これは高価であり、低速デバイスでスタッターとして表示されます。

実用的なルールは、できる限りモーションをtransformopacityとして表現することです。何かを動かしたいですか?topではなくtranslateを使用します。それをサイズ変更したいですか?widthではなくscaleを使用します。それが表示されたいですか?heightをゼロからアニメートするのではなく、opacityをフェードします。

css
/* コスト:レイアウトプロパティをアニメートしています */
.panel {
  transition: height 0.3s;       /* すべてのフレームでレイアウトを再計算します */
}

/* 安い:同じ効果、transformとして表現 */
.panel {
  transition: transform 0.3s;
  transform: scaleY(0);          /* レイアウトワークなし */
}

これは、transformが隣人を邪魔しない理由に繋がります。それはレイアウトに触れることはありませんが、ブラウザはページを再度実行することなく、それをアニメートできます。色やバックグラウンドトランジションにも到達する場合は、色とバックグラウンドはそれらのどれが補間するかをカバーします。

これはDeep Diveの前のセクションはそれを指しました。transformopacityが安いおよびほぼすべての他のものをアニメートすることはできません。これはブラウザのレンダリングパイプラインに帰結し、3段階で実行されます。レイアウトはすべてのボックスのサイズと位置を計算します。ペイントはピクセルを埋めます。色、テキスト、境界線。コンポジットは、最終フレームに描画層を組み立てます。これはGPUが駆動できるステージです。

transformまたはopacityをアニメートすることは、完全にコンポジットステージで実行できます。ブラウザは要素を描画し、独自の**コンポジタレイヤー**に昇格させます。これは、GPUが独立して移動およびブレンドできる別々に描画されたサーフェスです。各フレームのみ新しい位置または不透明度でそのレイヤーを再整形します。レイアウトはありません。再描写はありません。代わりにwidthまたはtopをアニメートすると、レイアウトが無効になり、ブラウザはすべてのフレームで幾何学を再計算して再描画するように強制され、これはロード下でフレームをドロップすることです。

css
/* 複合のみ:安い、GPU優しい */
.card {
  transition: transform 0.2s, opacity 0.2s;
}

/* すべてのフレームでレイアウトと絵を引き起こします:これらをアニメートするのは避けてください */
.card-heavy {
  transition: width 0.2s, top 0.2s;
}

will-changeは、プロパティがアニメートされようとしていることを示す場合、ブラウザがあらかじめレイヤーを昇格させることができるようにします。will-change: transformを使用します。それをめったに使用し、アニメーションが終了したら削除します。各昇格レイヤーはメモリを費やし、すべてを昇格させることは目的を破壊し、ページを遅くすることができます。測定されたスタッターの対象となる修正として扱い、デフォルトではありません。

イージングはもう一つのレバーが正確に名前を付ける価値があります。タイミング関数は、経過時間を進行状況にマッピングする曲線です。ease-out(高速その後遅くなる)は入場に適しており、要素は到着し、落ち着きます。ease-inは出口に適しており、linearは回転スピナーのような継続的なモーションに適しています。何か習慣について、cubic-bezier(x1, y1, x2, y2)は2つのコントロールポイントで曲線を定義し、組み込みキーワードは下の名前付きキュービックベジアーです。パフォーマンス予算を念頭に置いてください。フレーム(60fpsで約16ms)の時間内に留まることを目指し、複合のみのプロパティをアニメートし、will-changeに到達する前にプロファイラーに到達します。これらのいくつかをカスタムプロパティから駆動している場合、インターフェース全体で期間とイージングを一貫して保つことができます。

JunoWhat to animate, and why it matterstransformopacityをアニメートし、widthheighttop、またはmarginをアニメートすることから離れます。これら2つはブラウザが移動するのが最も安いため、モーションは低速デバイスでも滑らかなままです。完全ななぜ後で学びますが、習慣は今開始する価値があります。
JunoWhat to animate, and why it matters モーションをtransformopacityとして表現します。topの代わりにtranslateを使用し、widthの代わりにscaleを、ゼロからheightをアニメートするのではなくopacityをフェードします。レイアウトプロパティをアニメートすると、ブラウザがすべてのフレームでレイアウトをやり直すようにします。低速デバイスでスタッター。これは、transformが隣人を単独にしたままにする理由です。それはレイアウトに触れることは決してありません。
JunoWhat to animate, and why it matterstransformopacityは複合ステージで独自のGPUレイヤーでアニメートできるため、レイアウトと描画をスキップします。widthtopはすべてのフレームでレイアウトを無効にし、負荷下でフレームをドロップします。測定されたスタッターの対象となる修正としてwill-changeを使用し、その後削除します。各昇格レイヤーはメモリを費やします。ジェスチャーに合ったイージングを選択し、入場にease-outを選択し、最適化する前にプロファイラーをプロファイルします。