カルーセルのスライド効果は、カルーセルに視覚的な魅力を加える優れた方法です。ユーザーがスライドをスクロールすると、各スライドがスクロールポートに入り、中央に移動し、終了する際にアニメーション化されます。たとえば、スライドをフェードイン / フェードアウトしたり、回転させたり、サイズを拡大 / 縮小したりできます。これにより、動的で魅力的なユーザー エクスペリエンスが実現します。単純なエントリ / 終了アニメーションとは異なり、この効果では、1 つの連続したアニメーションを使用して、スクロールポート全体でスライドの表示を制御します。
導入方法
カルーセルのスライド効果を作成する方法は次のとおりです。
スクローラーを作成する: この要素は、カルーセル スライドのコンテナとして機能します。この例では、
overflow-x: scrollを使用して水平スクロールを可能にしています。<ul class="scroller"> <li class="entry">1</li> <li class="entry">2</li> <li class="entry">3</li> … </ul>.scroller { overflow-x: scroll; }アニメーションを定義する: スライドがスクロールポートを通過する際の状態を定義する CSS アニメーションを作成します。キーフレームは、アニメーションのどの部分にも定義できます。たとえば、
50%キーフレームを含めることで、スライドがスクロールポートの中央にあるときの状態を定義できます。この例では、scaleプロパティにより、スライドが中央に近づくにつれて大きくなり、離れるにつれて小さくなります。@keyframes animate { 0% { scale: 0.5; } 50% { scale: 1; } 100% { scale: 0.5; } }アニメーションと
view-timelineを適用する: アニメーションをカルーセル スライドに適用し、コンテナをスクロールする要素を追跡するview-timelineにリンクします。.scroller > * { animation: animate auto linear both; animation-timeline: view(inline); }デフォルトでは、
view()はblock軸上の要素をトラッキングします。inline軸でトラッキングする必要がある場合は、view(inline)を使用できます。
コード例
このコードは、匿名のビュー タイムラインを使用して、スクロール時に水平スクローラーのカルーセル アイテムをアニメーション化します。
@keyframes animate {
0% {
scale: 0.5;
}
50% {
scale: 1;
}
100% {
scale: 0.5;
}
}
.scroller > * {
/* Applies the animation using an `auto` duration */
animation: animate auto linear both;
/* Sets the animation timeline to use an anonymous view progress timeline, tracking the element's progress through the scroller on the inline axis */
animation-timeline: view(inline);
}
このコードは、名前付きの view-timeline を使用して、スクロール時に水平スクローラーのカルーセル アイテムをアニメーション化します。
@keyframes animate {
0% {
scale: 0.5;
}
50% {
scale: 1;
}
100% {
scale: 0.5;
}
}
/* This creates a named view-timeline on each carousel item. The timeline is used to drive the animation that is applied on the same element. */
.scroller > * {
/* Applies the animation using an `auto` duration */
animation: animate auto linear both;
/* Defines a named view progress timeline, tracking the element's progress through the scroller on the inline axis */
view-timeline: --item inline;
/* Sets the animation timeline to use the named view progress timeline defined above */
animation-timeline: --item;
}
ベスト プラクティス
スクロール駆動型アニメーションを使用する場合は、スムーズでアクセスしやすいエクスペリエンスを実現するために、いくつかのベスト プラクティスに従うことが重要です。
- 推奨: 機能検出を含める。すべてのブラウザがスクロールドリブン アニメーションをサポートしているわけではありません。
@supports ((animation-timeline: view()) and (animation-range: entry))を使用してサポートを確認し、サポートしていないブラウザに代替を提供します。- 部分的にしかサポートしていないブラウザを除外するには、ここに
(animation-range: entry)チェックを含める必要があります。 - フォールバック戦略に
scroll-timeline-polyfillパッケージを使用しないでください。このパッケージは機能が完全ではなく、既知の問題が多数あります。 - アニメーションが装飾的なものにすぎない場合は、プログレッシブ エンハンスメントを選択し、代替手段を提供しないでください。
- 部分的にしかサポートしていないブラウザを除外するには、ここに
- 推奨事項: ユーザーの設定を尊重します。ウェブ上でのモーションを好まないユーザーもいます。
prefers-reduced-motionメディアクエリを使用して、これらのユーザーに対してアニメーションを無効にするか、アニメーションを減らします。 - 推奨: パフォーマンスの高い CSS プロパティのみをアニメーション化する。アニメーションを最もスムーズにするには、ブラウザのコンポジタ スレッドで処理できるプロパティ(
transformやopacityなど)のみをアニメーション化します。widthやheightなどの他のプロパティをアニメーション化すると、パフォーマンスの問題が発生する可能性があります。 - 推奨: 正しい宣言順序を使用する。
animation略式プロパティを使用する場合は、略式プロパティがタイムラインをリセットしないように、animation-timelineとanimation-rangeをその後に宣言します。
複数の DOM 要素を同じタイムラインに基づいてアニメーション化する必要がある場合や、view-timeline が定義されている要素の子をアニメーション化する必要がある場合は、名前付きの view-timeline を使用することをおすすめします。アニメーション化する要素が view-timeline を定義する要素でもある場合は、view() を使用して匿名の view-timeline を使用できます。
view() 関数を使用してスクロール駆動型アニメーションを作成する場合:
- 任意: トラッキングする軸を明示的に指定します。デフォルトの
block軸をターゲットにしない場合(水平スクローラーなど)、view(block)またはview(inline)でトラッキングする軸を明示的に指定します。
view-timeline プロパティを使用してスクロール駆動型アニメーションを作成する場合:
- 推奨: 名前には CSS
<dashed-ident>を使用します(例:view-timeline: --my-custom-name)。 - 任意: トラッキングする軸を明示的に指定します。デフォルトの
block軸をターゲットにしない場合(水平スクローラーなど)、view-timeline-axisでトラッキングする軸を明示的に指定します。 - 推奨: ルックアップのスコープが機能することを確認します。
view-timelineを宣言している要素が、アニメーション化された要素のフラットツリーの祖先でない場合は、共有の祖先でtimeline-scopeを使用して、view-timelineの名前の可視性を引き上げます。
ブラウザのサポートとフォールバック戦略
そのため、通常はフォールバック戦略が必要です。
スクロール駆動型アニメーションをサポートしていないブラウザでは、フォールバックを使用して視覚効果を再現できます。フォールバックは通常、スクロール リスナー(ScrollTimeline 効果の場合)または IntersectionObserver API(ViewTimeline 効果の場合)を使用して構築されます。
スクロールドリブン アニメーションのサポートが組み込まれているブラウザでは、常にネイティブ CSS 実装を使用してください。その方がパフォーマンスが向上します。
フォールバック アプローチを使用してすべてのエフェクトを再現できるわけではありません。
このユースケースでは、次のスクリプトで、スクロール駆動アニメーションをサポートしていないブラウザにフォールバックを適用します。Web Animations API(Element.animate())を使用して、カルーセル内の各アイテムの一時停止アニメーションを作成します。次に、スクローラーの scroll イベントをリッスンし、スクローラー内のアイテムのスクロールの進行状況に基づいて、各アニメーションの currentTime を更新します。
// Fallback for browsers that don't support scroll-driven animations
if (!CSS.supports('(animation-timeline: view()) and (animation-range: entry)')) {
const scroller = document.querySelector('.scroller');
const entries = document.querySelectorAll('.entry');
// Create a map to store animations
const animations = new Map();
entries.forEach(entry => {
const animation = entry.animate(
{
scale: ['0.5', '1', '0.5']
},
{
duration: 1, // We'll control the time ourselves
fill: 'both'
}
);
animation.pause();
animations.set(entry, animation);
});
// Update animations on scroll
const tick = () => {
const scrollerRect = scroller.getBoundingClientRect();
entries.forEach(entry => {
const animation = animations.get(entry);
if (!animation) return;
const entryRect = entry.getBoundingClientRect();
const progress = (entryRect.left + entryRect.width / 2 - scrollerRect.left) / scrollerRect.width;
animation.currentTime = progress;
});
};
scroller.addEventListener('scroll', tick);
tick();
}