JavaScriptを使わずに高度なCSSカルーセルを作成する

最終更新: 05/24/2026
  • 最新のCSSのscroll-napを使えば、JavaScriptを使わずに、シンプルなスクロールをスムーズなページ分割カルーセルに変換できます。
  • ::scroll-button() や ::scroll-marker() のような新しい擬似要素は、純粋な CSS でアクセシブルなカルーセル コントロールを生成します。
  • CSSのみの戦略に、慎重なフォールバック処理とARIAを組み合わせることで、高速で堅牢かつ包括的なカルーセルを実現できます。
  • JavaScriptはオプションとなり、真の無限ループや複雑な状態を持つ動作といった特殊なケースのために予約される。

JavaScriptなしのCSSカルーセル

最新のCSSだけでカルーセルを構築することは、もはや夢物語ではない。これは非常に現実的で、すぐに使えるオプションであり、多くの場合、従来のJavaScriptスライダーライブラリよりも優れたパフォーマンスを発揮します。 スクロールスナップ、スクロール駆動アニメーション、実験的なカルーセル擬似要素、堅牢なアクセシビリティプリミティブ軽量で耐久性に優れた回転式ターンテーブルを出荷でき、しかも滑らかでインタラクティブな操作感と洗練された仕上がりを実現できます。

数枚のスライドを表示するためだけに50KBのJavaScriptバンドルを取り込むのにうんざりしているならこのガイドでは、最新のCSSで何ができるかを解説します。CSSのみのカルーセルの背後にある重要な概念、スクロールスナップとの連携方法、新しい機能の活用方法などを詳しく見ていきます。 ::scroll-button() and ::scroll-marker() 擬似要素、そしてアクセシビリティとパフォーマンスを最優先事項として扱いながら、自動再生や循環的な動作をどのように組み込むか。

CSSのみのカルーセルがようやく本格的な選択肢となった理由

長年、「カルーセル」は「JavaScriptプラグイン」とほぼ同義語だった。Swiper、Glide、あるいは独自開発のスライダーといったソリューションが主流のアプローチでした。これらはナビゲーション、状態管理、キーボードサポート、タッチジェスチャーに対応していましたが、重量が増加し、至る所にイベントリスナーが必要となり、DOM操作もかなり複雑になるという欠点がありました。

現代のCSSは、そのギャップのほとんどを静かに埋めてきた。次のような特性を持つ scroll-snap-type and scroll-snap-align水平スクロールや垂直スクロールをページ分割されたエクスペリエンスに変えることができます。さらに、CSS Overflow Level 5 仕様では、ブラウザ生成の スクロールボタンとマーカー フル機能のカルーセルUIのように動作するが、すべてCSSで宣言されている。

最大のメリットは、コアとなるUXに関する責任がJavaScriptコードではなくブラウザに委ねられる点です。スクロールの物理演算、キーボードナビゲーション、フォーカス順序、さらにはカルーセルのコントロールに対するARIAロールまで。多くの場合、プラットフォームが標準で提供しているものよりも、アクセシビリティが高くパフォーマンスに優れたものを構築するのは本当に難しい。

CSSカルーセルのもう1つの大きな利点は、回復力です。JavaScriptの読み込みに失敗した場合でも、スクリプトがブロックまたは無効化されているユーザーは、完全に使用可能なスクロール可能なアイテムセットを利用できます。ハイドレーション処理や、遅延読み込みコードによるレイアウトのずれは発生せず、時間の経過とともに不具合が生じる可能性のある要素もはるかに少なくなります。

コアとなる構成要素:スクロールスナップ機能を備えたスクロール可能なコンテナ

CSSのみで構成されたカルーセルはすべて、通常のスクロール可能なコンテナとして始まります。水平方向にスクロールできるシンプルなスライドリストを想像してみてください。そこにスクロールスナップ機能を追加することで、ビューポートが各スライドに自然に固定されるようにします。

水平カルーセルの最小限のHTML構造は意図的にシンプルです: ラッパー要素と、その中に一連のスライドアイテムがあります。 ul   li 要素、または div 子供連れ divs—CSSがほとんどの処理を担ってくれるので、デザイン上必要でない限り、すべての子要素に特別なクラスを付ける必要はありません。

基本的なスクロールスナップの設定は、CSSでは次のようになります。全幅表示、単一スライド表示を想定:

.carousel { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scroll-behavior: smooth; }
.carousel-item { flex: 0 0 100%; scroll-snap-align: center; }

ここではコンテナが display: flex 子供たちを水平に並べる, overflow-x: auto スクロールを有効にするには。魔法は scroll-snap-type: x mandatoryこれは、水平スクロールが常に有効なスナップポイントに落ち着くようにブラウザに指示し、 scroll-snap-align: center 各スライドには、それらのスナップポイントを定義するものが記載されています。

フレックスボックスとスクロールスナップの組み合わせは、まるでカルーセルのようです。ユーザーがスクロールまたはスワイプすると、最も近いスライドが所定の位置にスナップします。ネイティブスクロールを活用するため、スマートフォンやタブレットでのタッチ入力は問題なく動作します。 ジェスチャーハンドラー または追加の図書館。

1回の閲覧につき1つのアイテムに制限はありません複数のカードを一度に表示するマルチカラムカルーセルでは、アイテムの幅を柔軟に設定できます。例:

.carousel-item { flex: 0 0 calc(33.333% - 1rem); margin: 0 0.5rem; scroll-snap-align: center; }

このバリエーションでは、例えば、ビューポートごとに3枚のカードを少し間隔を空けて表示できます。スナップ機能の利点はそのままに、ユーザーは単一のヒーロースライドではなく、カードのページをスライドして閲覧します。これは、商品リストやギャラリーに最適です。

::scroll-button() 擬似要素を使用したスクロールボタン

スナップスクロール機能を手に入れたら、次に多くの人が求めるのは明確なナビゲーションボタンです。—カルーセルを左右に微調整する前後のコントロール。従来は、 <button> 要素を操作し、クリックイベントをバインドして、スクロールする距離を計算します。

CSS Overflow 5 仕様では、 ::scroll-button()、ブラウザがそれらの面倒な処理をすべて実行できるようにする擬似要素これは現在Chrome 135以降で利用可能となっており(最初は実験的なフラグが設定されていることが多い)、今後カルーセルがどのように作成されるかを示す一例と言えるでしょう。

スクロールボタンは、他の擬似要素と同じように宣言します。例えば、カルーセルに左右のボタンを生成するには、次のようにします。

.carousel::scroll-button(left) { content: "⬅" / "Scroll left"; }
.carousel::scroll-button(right) { content: "⮕" / "Scroll right"; }
.carousel::scroll-button(*) :focus-visible { outline-offset: 5px; }

この CSS を適用すると、ブラウザは実際に実際の <button> スクロールコンテナの兄弟要素それらをスクローラーに接続し、適切な役割を割り当て、動作を設定します。通常、1回のクリックでスクロール領域の約85%がスクロールされ、これはほとんどのカルーセルレイアウトにおける「ページ」のように感じられます。

デザインがクリックごとに正確に1つの全幅アイテムを想定している場合これらの擬似要素を、各子要素にさらに厳密なスナップを追加することで組み合わせることができます。 scroll-snap-stop: alwaysこれにより、ビューポートは途中で停止するのではなく、アイテムの境界に確実に着地するようになります。

ここでのコンテンツプロパティは二重の役割を果たします最初の値はユーザーが視覚的に見るもの(この場合は矢印文字)で、2 番目の文字列は支援技術に公開できるアクセシブルなフォールバックテキストです。これらのボタンは CSS で自由にスタイル設定や配置をしたり、次のような関数を使用したりできます。 anchor() レイアウトに正確に合わせるため。

::scroll-marker() と ::scroll-marker-group を使用したスクロールマーカー

カルーセルの下に表示されるドットやラベル(「ページネーション記号」や「マーカー」と呼ばれることが多い)も、よくある要件の一つです。これらは、存在するアイテムの数と現在表示されているアイテムを示し、ユーザーが特定のスライドに直接ジャンプできるようにします。

その ::scroll-marker() 擬似要素を使用すると、アンカーリンクやスパンを手動で生成することなく、これらの指標を取得できます。各マーカーは基本的にナビゲーションです <a> ブラウザによって作成される要素で、対応するスクロール項目を指し示し、キーボード操作やスクリーンリーダーによるナビゲーションに関与します。

これを設定するには、ブラウザにマーカーグループを配置する場所を指定します。   scroll-marker-groupマーカーを作成する要素を指定します。最小限の構成例は次のようになります。

.carousel { scroll-marker-group: after; }
.carousel > li::scroll-marker { content: " "; }
.carousel > li::scroll-marker:target-current { background: var(--accent); }

ブラウザは ::scroll-marker-group コンテナをスクローラーの兄弟要素として配置し、選択された子要素ごとにマーカーを1つずつ配置します。この簡単な例ではマーカーは空のドットとしてレンダリングされますが、次のように変更することで「シーズン 1」のようなテキスト、アイコン、サムネイルも簡単に使用できます。 content プロパティ。

これらのマーカーは、通常のスクロールバーと比べて何が特別なのでしょうか? それらは実際のナビゲーションリンクです。ユーザーは意味のある位置に直接ジャンプでき、便利なセマンティクスが付属しています。 :target-current 現在表示されているスライド、またはスナップされたスライドに対応するマーカーを示す状態。キーボード操作ではフォーカスグループのように動作し、スクリーンリーダーではタブリストのようなコントロールとして表示できます。

この戦略は、スクロール機能が個々のアイテムではなく論理的なまとまりを表す場合に特に効果的です。例えば、10エピソードごとに10個のマーカーを作成する代わりに、シーズン1とシーズン2の冒頭にジャンプするマーカーをそれぞれ2つ作成することもできます。どの「注目ポイント」を対象とするかは、自由に決定できます。

ボタンとマーカーを組み合わせて完全なカルーセルUIを作成する

あなたが置くとき ::scroll-button() and ::scroll-marker() 同じスクロール画面にまとめて表示結果として、ユーザーがカルーセルだとすぐに認識できるUIが完成します。前の/次のコントロール、現在位置を示すマーカーの列、そしてスライド間のスムーズなスナップ機能などが含まれます。

従来のJavaScriptスライダーとの大きな違いは、このロジックのほとんどがブラウザ内で実行されるようになった点です。ボタンとマーカーは、適切なARIAロールを持つ生成要素であり、タブ順序に適切に統合され、各サイトごとに再設計されるのではなく、基盤となるブラウザチームによって設計されたアクセシビリティストーリーに基づいています。

このアプローチは、いくつかの非常に実用的な利点をもたらします。JavaScriptが無効になっている場合でも動作し、ハイドレーションのちらつきやタイミングの問題を解消し、CSSレイアウト時にコントロールが既知であるため累積レイアウトシフトを軽減し、装飾を追加したい場合はスクロール駆動アニメーションやスクロール状態クエリとシームレスに統合します。

タッチデバイスでは、指での操作に自然と馴染む。 スクロールコンテナはあくまでネイティブのスクロール機能であるためです。デスクトップ環境では、マウスホイールとキーボード入力は期待どおりに動作し、生成されたコントロールのフォーカスインジケーターは、デザインやアクセシビリティに関するガイドラインに合わせてスタイルを設定できます。

メンテナンスの観点から言えば、「作業量を減らして、より多くの成果を上げる」というのは、かなり的確な表現と言えるでしょう。複数のプロジェクトでカルーセル実装のロジックを維持する代わりに、共有され標準化されたプラットフォーム機能を利用することで、追加作業なしで時間の経過とともに改善されていきます。

実際のプロジェクトでスクロールスナップを機能させる

新しい擬似要素をいったん無視したとしても、スクロールスナップだけでも多くの本番環境のカルーセルには十分です。最新のブラウザエンジンにおけるスクロールスナップのサポートは安定しており、マウスホイールとタッチジェスチャーの両方で動作が予測可能です。

最も単純なシナリオでは、HTMLカルーセルは div 内部に一連の画像ありコンテナに次のようなクラスを指定できます。 .carousel 子画像は分類せずにそのままにしておきます。配置とスクロールはCSSで処理します。

オンにすることで scroll-behavior: smooth 容器にスナップポイント間のスクロールが、ぎこちない動きではなく、心地よいアニメーションになります。これは、ユーザーがマーカーやアンカーリンクをクリックしたとき、またはハイブリッド構成でプログラムによってスクロールをトリガーしたときに特に顕著です。

各キースクロールスナッププロパティはそれぞれ非常に異なる役割を果たします. scroll-snap-type 軸を定義し、スナップが必須か単なるヒントかを定義します。 scroll-snap-align 子要素については、子要素が画面に固定される場所(開始、中央、終了)を指定します。 scroll-snap-stop: always ブラウザが高速スクロール時にスナップポイントをスキップするのを防ぎます。

これらのプロパティを組み合わせることで、カルーセルの操作感を細かく調整できます。大きなコンテンツセクションに適した、穏やかで寛容なスナップ動作から、アイテムの「間」に止まってはいけないヒーローバナーに最適な、厳密なスライドごとの動作まで。

これは純粋なCSSなので、レイアウトをレスポンシブに簡単に調整できます。メディアクエリを使用すると、狭い画面ではビューごとに 1 枚のスライドを表示し、広いデスクトップではビューごとに複数のスライドを表示するように切り替えることができます。 flex-basis アイテムの数。JavaScriptブレークポイント、リサイズリスナー、幅の再計算は不要です。

実験的な擬似要素と特徴検出

新しいカルーセル指向の擬似要素—::scroll-button(), ::scroll-marker() and ::scroll-marker-group強力でありながら、比較的新鮮である。この記事執筆時点では、Chrome 135以降で利用可能であり、多くの場合、実験的なフラグが必要となる。今後、他のエンジンにも順次展開される予定である。

サポートがまだ普遍的ではないため、本番環境では機能検出と適切なフォールバックに頼るべきである。. CSS を使用すると、 @supports アットルールとは、プロパティ認識に基づいて条件付きでルールを適用できる機能です。

シンプルなフォールバックナビゲーションストリップを定義することもできます。―カルーセルの下に配置されたリンクやボタンのセット―、そしてブラウザがネイティブのスクロールボタンをサポートしている場合はそのストリップを非表示にします。例:

.carousel-nav { display: flex; gap: 0.5rem; }
@supports (scroll-button-inline: both) { .carousel-nav { display: none; } }

ここに .carousel-nav 手動で作成された、IDを介してスライドを指すアンカーリンクを含めることができます。、のような <a href="#slide1">1</a>新しい scroll-button プロパティを理解するブラウザでは、ネイティブ コントロールが表示され、フォールバック ナビゲーションは非表示になります。古いブラウザでは、アンカー ナビゲーションが残され、スクロール スナップと組み合わされて、完全に使いやすいエクスペリエンスが提供されます。

このハイブリッド戦略により、次世代カルーセル機能を今日から安全に試すことが可能になります。特定のエンジンやフラグ設定に縛られることなく、これらの機能を実現できます。ブラウザのサポートが成熟するにつれて、擬似要素をより積極的に活用し、手動で記述する部分を減らすことができます。

CSSのみを使用したキーフレームアニメーションによる自動再生カルーセル

もう一つよくある要望は自動再生です。これは、マウスカーソルを重ねると一時停止するオプション付きで、自動的に再生が進むカルーセルです。自動再生にはUXやアクセシビリティに関する注意点があるものの、CSSアニメーションのみで実現することは可能です。

簡単なパターンとしては、スライドトラックの水平方向の移動をアニメーション化する方法があります。.

@keyframes slide {
0%, 20% { transform: translateX(0); }
25%, 45% { transform: translateX(-100%); }
50%, 70% { transform: translateX(-200%); }
75%, 95% { transform: translateX(-300%); }
100% { transform: translateX(0); }
}
.autoplay-carousel { display: flex; animation: slide 12s infinite; }
.autoplay-carousel:hover { animation-play-state: paused; }

この例では、キーフレームは各オフセットで一定時間経過してから次のスライドに進みます。トラックは最後にループして戻り、4枚のスライドが繰り返されるスライドショーのように見えます。カルーセルにカーソルを合わせるとアニメーションが一時停止するため、ユーザーは絶え間ない動きに邪魔されることなくコンテンツを確認できます。

健康や快適さの理由から、動きの少ない動作を好むユーザーを尊重するためアニメーションをメディアクエリで囲むことができます。

@media (prefers-reduced-motion: reduce) { .autoplay-carousel { animation: none; } }

これにより、動作の低減が要求されるシステムでは、スライドが静止状態を維持することが保証されます。これにより、自動再生は実質的に無効になりますが、手動スクロールやボタン/マーカーによるナビゲーションが提供されている場合は、それらも引き続き可能になります。

重要なトレードオフの一つは、キーフレームベースの自動再生がスクロールスナップと自動的に統合されないことである。ネイティブスクロールに頼るのではなく、コンテンツを手動で翻訳するため、スライドが半分しか表示されないことを防ぎ、レイアウトとのタイミングを同期させるために、アニメーションを慎重に設計する必要があります。

CSSカルーセルのアクセシビリティに関する考慮事項

アクセシビリティは、CSSベースのカルーセルが真価を発揮できる分野です。なぜなら、多くの複雑なロジックが、独自のコードから、綿密に設計されテストされたプラットフォームの動作へと移行するからです。

ネイティブスクロールとスクロールスナップを利用すると、キーボード、タッチ、マウスのサポートが自動的に継承されます。ユーザーは、イベントリスナーやカスタムハンドラーを使わずに、タブキーでスクロールしたり、矢印キーで移動したり、タッチスクリーンでスワイプしたり、ホイールでスクロールしたりできます。

実験的なスクロールボタンとマーカーはさらに一歩進んでいますブラウザは適切なセマンティクスでそれらを生成し、タブ順序に統合し、その状態を維持するため、ARIA属性をうっかり忘れたり、ラベルを間違えたりすることは非常に困難です。結果として得られるカルーセルコントロールは、独自に実装したものよりも一貫してアクセスしやすい傾向があります。

カルーセル領域に意味ヒントを追加することは可能であり、またそうすべきです。例えば、容器に印を付けて role="region" そして記述的な aria-label スクリーンリーダーのユーザーがコンポーネントが何を表しているかを理解するのに役立ちます。

<div class="carousel" role="region" aria-label="Product gallery">
<div class="carousel-item" aria-label="Slide 1 of 3">...</div>
</div>

すべてのインタラクティブ要素に視覚的なフォーカスインジケーターを確保することは依然として重要です。コントロールが独自のボタンやリンクであれ、ブラウザが生成した擬似要素であれ、フォーカスのアウトラインが削除されたり、見えなくなるほど小さくなったりしないように注意してください。 outline, outline-offset または、コントラスト要件を満たすために必要に応じて背景を変更する。

タッチターゲットのサイズも実用的な考慮事項の一つです。一般的なアクセシビリティガイドラインに準拠するため、コントロールのサイズは少なくとも44×44ピクセルにすることを目標にしてください。そうすることで、ユーザーが小さな画面で矢印やドットをタップする際に苦労することがなくなります。

自動再生機能を使用する場合は、ユーザーに明確な制御権限を与え、過度に激しい動きは避けてください。ホバー時に一時停止するか、明示的な一時停止ボタンを提供し、コンテンツが濃密またはテキストが多い場合は、自動再生をデフォルトでオフにすることを検討してください。 prefers-reduced-motionこれにより、より幅広いユーザーにとってカルーセルがより快適になります。

CSSで円形スクロールまたは「無限スクロール」を処理する

よく要望される動作の一つに、円形スクロールがあります。最後のスライドに到達してさらにスクロールすると、まるで物理的なメリーゴーランドが無限に回転しているかのように、スムーズに最初のスライドに戻ります。

現在、スクロールコンテナを本質的に円形にする直接的な純粋なCSSプロパティは存在しない。コンテンツを重複させない場合、ネイティブのスクロール機能には開始点と終了点があります。最後の項目に到達すると、それ以上スクロールしても先には進みません。

仕様書の作成者は、多くのUIカルーセルがこのループ動作を想定していることを認識している。また、新しいスクロールボタンやマーカーが標準化されたのと同様に、循環スクロールのためのプラットフォームレベルのソリューションを模索することにも積極的に関心が寄せられています。とはいえ、現時点では、単一のCSS宣言でブラウザにスクロール位置をネイティブにラップさせることはできません。

純粋なCSS構成では、ループをシミュレートするには、通常、トランスフォームをアニメーション化するか(自動再生キーフレームの例のように)、シーケンスの線形終了を受け入れる必要があります。シームレスな無限表示が絶対に必要で、コンテンツを複製できない場合は、現時点ではJavaScriptの方がより柔軟なツールです。

朗報は、主にCSSで構成されたカルーセルに、真に価値を高める少量のJavaScriptを組み合わせることを妨げるものは何もないということです。日常的なナビゲーションにはスクロールスナップやCSSボタンを利用し、スクロール位置を監視して必要に応じて末尾から先頭にジャンプするスクリプトを数行追加することもできます。

リッチなカードベースのカルーセルにおけるHTML/CSSとJavaScriptの比較

新米開発者がよく直面するジレンマは、より複雑なカードカルーセルをJavaScriptで記述する必要があるかどうかである。人々は、単純な画像からさまざまなコンポーネントを備えたレスポンシブカードへと進むと、CSSだけではもはや有効ではなくなるとよく考えます。

実際には、CSSのscroll-snapは、リッチカードでもプレーンな画像でも同様に機能します。各カードがスクロールコンテナ内のブロックである限り、カードにスナップしたり、周囲をアニメーション化したり、追加のスタイルを重ねたりすることができます。タイトル、ボタン、テキストの断片、さらには埋め込みメディアも、基本的な動作を変えるものではありません。

JavaScriptが真価を発揮するのは、条件付き動作と複雑な状態管理においてである。カルーセルでカードを動的にフィルタリングしたり、スライドの順序を変更したり、他のコンポーネントと同期したり、新しいコンテンツをその場で取得したり、高度にカスタマイズされたロジック(「このドットがクリックされたら、全く関係のないカードを表示する」など)をサポートする必要がある場合は、JavaScript を使用すると、CSS だけの場合よりも簡単にビジネスロジックを表現できます。

しかし、驚くほど多くの日常的なスライダーは、基本的に直線的に進む静的なアイテムのリストです。そういった場合、大規模なJavaScriptライブラリをインポートするよりも、数行のCSSを使用する方が、理解しやすく、パフォーマンスも向上します。scroll-snapや新しい擬似要素を理解することで、JavaScriptは本当に効果を発揮する稀なケースにのみ使用できるようになります。

フロントエンド開発をまだ学習中であれば、CSSカルーセルをデフォルトのベースラインとして扱うことは素晴らしい習慣です。まずはHTMLとCSSから始め、明確な限界に直面した場合にのみスクリプトに手を出すようにしましょう。こうすることで、プラットフォームが既に何ができるのかをより深く理解でき、より簡潔でクリーンなコードベースにつながることがよくあります。

改めて考えてみると、スクロール、スナップ、ボタン、マーカー、スクロール状態クエリなどに関するCSSの新たな機能群が注目されている。 スクリプトを多用するウィジェットから、宣言的なコンポーネントへとカルーセルを変革しました。コアとなるページング動作にはscroll-snapを使用し、 ::scroll-button() and ::scroll-marker() サポートされている場合、機能検出とアクセシビリティのベストプラクティスを適用することで、従来のJavaScript駆動型スライダーよりも高速で堅牢、かつ保守が容易なカルーセルをリリースできます。同時に、循環ロジックや高度なインタラクションが真に必要とされる場合には、JavaScriptを組み込むための十分な柔軟性も維持できます。

プロパティ CSS タッチアクション
関連記事
CSS タッチアクションのプロピエダ: 正確な操作性を実現
関連記事: