ホームページ > 記事 > ウェブフロントエンド > 表示プロパティとサイズプロパティを使用して CSS アニメーションを簡素化する
サレハ・ムバシャール著✏️
最近まで、アニメーション化できる CSS プロパティの数は限られていました。たとえば、フェードインまたはフェードアウト効果を作成するには、display プロパティの代わりに opacity プロパティを使用するのが一般的です。これは後者はアニメーション化できないためです。ただし、問題は、要素が視覚的に非表示になっても、ページ上にはまだ存在していることです。
最近、Chrome にはこの問題を解決し、開発プロセスをはるかに簡素化する新機能が導入されました。この記事では、表示およびサイズのプロパティをアニメーション化する従来の方法と、これらの新機能を比較します。
おそらく、ある時点で CSS を使用して要素にフェードイン/フェードアウト効果を作成する必要があったと思います。主な方法は、要素の不透明度にアニメーションまたはトランジションを適用することです。ただし、不透明度をゼロに設定しても、実際に要素が削除されるわけではありません。要素が非表示になるだけです。ほとんどの場合、それで十分です。
しかし、ユーザーが項目を削除できる To Do リストがあるとします。項目がフェードアウトするような終了アニメーションを作成したい場合は、通常は不透明度を使用します。ただし、リストの高さを調整する必要がある場合は、表示をなしに設定する必要もあります。ここでの問題は、項目が視覚的に消えても、依然として DOM 内のスペースを占有し、レイアウトやユーザー操作などに支障をきたすことです。
ここでは 2 つのアプローチを並べて比較しています。1 つは不透明度のみを使用する方法、もう 1 つは不透明度と表示を組み合わせた方法です。以下の例を試して違いを確認してください:
CodePen で、Saleh-Mubashar (@saleh-mubashar) による Pen Simple Todo アプリの比較を参照してください。
表示と不透明度を組み合わせるとレイアウトがどのように変化するかに注目してください。一方、不透明度だけを使用するとリストに隙間が残ります。 2 番目の方法 (不透明表示) はレイアウトの問題を解決しますが、フェードが終了する前に display: none が適用されるため、スムーズなフェードアウト効果が妨げられます。これにより、徐々に消えていくのではなく、突然消えてしまいます。
たとえば、opacity プロパティは 0 から 1 にスムーズに遷移できます。ただし、display プロパティには数値範囲がないためアニメーション化できません。その状態は none、block、またはその他の値のようなバイナリです。中間の値がないため、CSS は表示をアニメーション化できません。
同様に、開発者は、height: auto などの要素の固有のサイズをアニメーション化しようとするときに、多くの場合課題に直面します。これは、アコーディオンなどの折りたたみ可能なセクションのトランジションによく使用されます。閉じたときの高さは 0px から始まり、開いたときにコンテンツに合わせて拡張されます。通常、高さなどのサイズ プロパティはアニメーション化できますが (数値の開始値と終了値があるため)、自動との間でアニメーション化すると問題が発生します。ブラウザは 0px と auto の間のステップを計算できません。したがって、複雑な回避策を使用する必要があります。
表示と要素のサイズをアニメーション化する際の課題に対処する方法はいくつかあります。このセクションでは、CSS と JavaScript の両方を使用した最も一般的なソリューションについて説明します。
CSS を使用して表示プロパティがアニメーション化できない問題を解決するには、いくつかの方法があります。最も信頼できる方法は、高さや幅などのサイズ プロパティとともに不透明度を使用することです。この場合、size プロパティを使用して、DOM から要素を効果的に削除します。これは、transition-delay プロパティを使用して実行できます。基本的に、サイズの遷移に遅延を追加します。これは、不透明度の遷移に設定された時間と同じです。要素がフェードアウトすると、そのサイズはすぐにゼロに設定され、display: none が適用されていたかのようにレイアウトから効果的に削除されます。
再び ToDo リストを例として使用すると、実装は次のようになります。
li { height: 50px; /* any measurable value, not "auto" */ opacity: 1; transition: height 0ms 0ms, opacity 400ms 0ms; } .fade-out { overflow: hidden; /* Hide the element content, while height = 0 */ height: 0; opacity: 0; padding: 0; transition: height 0ms 400ms, padding 0ms 400ms, opacity 400ms 0ms; }
ここでの秘訣は、不透明度が 0 にフェードアウトした後、遅延の後に高さとパディングを 0 に設定することです。遅延と不透明度の長さは同じである必要があります (この場合は 400ms)。高さ: 0 は、リスト項目がレイアウトと相互作用しないようにします。前に説明したように、高さはコンテンツに基づいて動的に自動調整されます。したがって、アニメーション化することはできません。したがって、アニメーションが適切に動作するには、要素の高さが特定の固定高であることを確認する必要があります。
可視性を非表示に設定することも、よく使用される方法です。ただし、これは DOM から要素を削除するわけではなく、通常どおりレイアウトに影響します。つまり、周囲の要素の位置に影響します。
要素をその固有サイズ (または高さ: 自動) にアニメーション化するための最も一般的な CSS ソリューションは、高さの代わりに max-height を使用することです。これは最もクリーンな実装ではありませんが、仕事は完了します。基本的に、max-height は要素が取得できる値よりも大きな値に設定します。このようにして、固定高さをアニメーション化するのと同様に、スムーズな遷移を模倣します。
.collapsible { max-height: 0; overflow: hidden; transition: max-height 0.4s ease; } .collapsible.open { max-height: 500px; }
このアプローチの最も明白な欠点は、最大高さを要素内の実際のコンテンツよりも常に大きくする必要があることです。もう 1 つの問題は、コンテンツの高さが max-height 値と完全に一致しない限り、遷移のタイミングが不正確に感じられる可能性があることです。
コンテンツの高さは 400 ピクセルですが、最大高さを 1000 ピクセルに設定したとします。アニメーションは技術的には継続時間全体 (たとえば 2 秒間) 継続します。ただし、視覚的には、要素はコンテンツの実際の高さ (400 ピクセル) に達するとすぐに成長が止まりますが、最大高さは 1000 ピクセルに移行し続けます。したがって、この場合、移行期間は指定した期間よりも短くなります。
上記で説明した CSS ソリューションはすべて非常に複雑で、予測できない結果を招く可能性があります。最近まで、これを実現する最も信頼できる方法は JavaScript を使用することでした。
不透明度の遷移後に表示なしを適用するには、setInterval 関数または setTimeout 関数を使用して、不透明度の遷移時間に一致する遅延を追加します。この遅延の後、表示をなしに設定できます。以下に例を示します:
li { height: 50px; /* any measurable value, not "auto" */ opacity: 1; transition: height 0ms 0ms, opacity 400ms 0ms; } .fade-out { overflow: hidden; /* Hide the element content, while height = 0 */ height: 0; opacity: 0; padding: 0; transition: height 0ms 400ms, padding 0ms 400ms, opacity 400ms 0ms; }
このコードでは、ボタンをクリックした後、要素が 1 秒かけてフェードアウトし、その後すぐに表示がなしに設定されます。つまり、要素はレイアウトから削除されます。
同様に、固有のサイズをアニメーション化するには、JavaScript で要素の高さを計算し、その値を高さのエンドポイントとして使用できます。このアプローチは、より信頼性が高く、正確です。ただし、依然として高さのプロパティでアニメーション化していることに注意してください。
ここでの明白な利点は、要素の実際のコンテンツに基づいて高さを動的に設定し、max-height を使用して推測するのではなく、トランジションが実際の高さと一致することを保証することです。
その方法は次のとおりです:
.collapsible { max-height: 0; overflow: hidden; transition: max-height 0.4s ease; } .collapsible.open { max-height: 500px; }
この例では、高さ 0 で始まるセクションを展開しています。scrollHeight を使用してコンテンツの全高を取得し、それをトランジションのエンドポイントとして使用します。移行が完了したら、高さを自動に切り替えます。これにより、ブラウザーがコンテナーのコンテンツに基づいてコンテナーの高さを自動的に調整できるようになります。このステップはオプションですが、コンテナ内のコンテンツが時間の経過とともに変化することが予想される場合に便利です。
次に、最近ブラウザに導入された、またはブラウザに導入される予定の新しい CSS 機能を見てみましょう。これらの新しいツールは、以前に説明したシナリオで JavaScript の必要性を排除し、よりクリーンで短い CSS を作成するのに役立ちます。
@keyframes アットルールを使用すると、アニメーション シーケンスの中間ステップを制御してアニメーションを作成できます。最新の更新により、キーフレーム タイムライン内で表示および [content-visibility](https://blog.logrocket.com/using-css-content-visibility-boost-rendering-performance/) プロパティをアニメーション化できるようになります。
表示なしとブロックの間を正確に補間しているわけではありません (それは不可能であるため)。代わりに、他のすべてのエフェクトが完了するのを待ってから、表示状態を切り替えます。これは、JavaScript で行ったこと (display: none を適用する前に遷移が完了するのを待つこと) に似ていますが、CSS を使用するとはるかに簡単になります。
Chrome 開発者ブログには、物事を明確にする非常にクールなデモがあります。
CodePen 上の web.dev (@web-dot-dev) によるペン フェードアウト カード - アニメーションを参照してください。
まず、不透明度が 250ms かけて 0 に設定されます。このシーケンスが完了すると、表示はすぐに none に設定されます:
li { height: 50px; /* any measurable value, not "auto" */ opacity: 1; transition: height 0ms 0ms, opacity 400ms 0ms; } .fade-out { overflow: hidden; /* Hide the element content, while height = 0 */ height: 0; opacity: 0; padding: 0; transition: height 0ms 400ms, padding 0ms 400ms, opacity 400ms 0ms; }
ここでの最大の利点は、最近まで CSS (または JavaScript) を使用して実装するのが非常に困難であった、表示プロパティを含むより複雑なアニメーションを比較的簡単に作成できるようになったということです。
新しい [transition-behavior](https://developer.mozilla.org/en-US/docs/Web/CSS/transition-behavior) プロパティを使用して、トランジションでフェードアウト効果を作成することもできるようになりました。 。これにより、表示などの個別のアニメーション動作を持つプロパティにトランジションを適用できます。 allow-discrete を使用すると、表示プロパティをアニメーション化できます。簡単な例を次に示します:
.collapsible { max-height: 0; overflow: hidden; transition: max-height 0.4s ease; } .collapsible.open { max-height: 500px; }
この記事では、フェードアウト効果についてかなり詳しく説明しました。しかし、逆の場合はどうでしょうか?エントリのアニメーションは扱いが難しく、多くの場合、JavaScript を介してのみ可能です。新しい @starting-style at-rule により、作業がはるかに簡単になります。
名前が示すように、これを使用すると、要素がページに表示される前にブラウザが検索できる要素にスタイルを適用できます。ここでエントリアニメーションの初期状態を設定できます。要素がレンダリングされると、デフォルトの状態に戻ります。
これが基本的な例です:
document.getElementById("fadeButton").addEventListener("click", function () { const element = document.getElementById("myElement"); element.style.opacity = "0"; setTimeout(() => { element.style.display = "none"; }, 1000); // Match this value with the duration in CSS });
DOM がロードされると、カードがフェードインします。 @starting-style はあらゆる種類のエントリ アニメーションに使用できます。 Chrome 開発チームによるもう 1 つの素晴らしい例を次に示します:
_CodePen の web.dev (@web-dot-dev) によるペン項目の遷移を参照してください。
_
calc() に似た calc-size 関数は、最近 Chrome 129 で導入されました。簡単に言えば、これを使用すると、固有のサイズに対して安全かつ確実に計算を実行できるようになります。現在、auto、min-content、max-content、fit-content の 4 つのキーワードの操作がサポートされています。
これは、要素をその固有のサイズに、またはその元のサイズにアニメーション化する場合に特に便利です。 calc-size を使用すると、CSS で現在指定できる任意の高さをゼロまたは小さな固定値にアニメーション化できます。以下は、折りたたみ可能なセクションを height: 0 から auto:
まで展開する簡単な例です。
li { height: 50px; /* any measurable value, not "auto" */ opacity: 1; transition: height 0ms 0ms, opacity 400ms 0ms; } .fade-out { overflow: hidden; /* Hide the element content, while height = 0 */ height: 0; opacity: 0; padding: 0; transition: height 0ms 400ms, padding 0ms 400ms, opacity 400ms 0ms; }
これらの機能のほとんどは主にアニメーションを強化するためのものであり、必須の DOM コンポーネントではありませんが、比較的新しいため、ブラウザーの互換性を確認する価値はあります。
この記事では、表示や要素のサイズなどの CSS プロパティをアニメーション化するときに開発者が直面する課題について検討しました。従来の方法では、直接アニメーション化できないプロパティのアニメーションを実現するには、CSS と JavaScript を使用した複雑な回避策が必要でした。
キーフレームを使用した表示のアニメーション化、calc-size() 関数、transition-behavior プロパティなどの新機能により、これらのアニメーションを簡単に実現できます。これらの関数により JavaScript が不要になり、よりシンプルな CSS アニメーションが可能になります。
Web フロントエンドがますます複雑になるにつれて、リソースを貪欲な機能がブラウザーに要求します。本番環境のすべてのユーザーのクライアント側の CPU 使用率、メモリ使用量などを監視および追跡することに興味がある場合は、LogRocket を試してください。
LogRocket は Web アプリやモバイル アプリ用の DVR のようなもので、Web アプリ、モバイル アプリ、または Web サイトで発生するすべてを記録します。問題が発生する原因を推測する代わりに、主要なフロントエンド パフォーマンス メトリクスを集計してレポートし、アプリケーションの状態とともにユーザー セッションを再生し、ネットワーク リクエストをログに記録し、すべてのエラーを自動的に明らかにすることができます。
Web アプリやモバイル アプリのデバッグ方法を最新化します。無料でモニタリングを始めましょう。
以上が表示プロパティとサイズプロパティを使用して CSS アニメーションを簡素化するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。