結論

カルーセルとは、複数の画像や内容を同じ場所で順番に切り替えて見せる UI(画面部品)です。場所を節約できる一方で、2枚目以降はほとんど見られないという調査があり、「使うかどうか」の判断と、使うなら「操作できる・止められる・軽い」作りが要点です。

この記事でわかること

  • カルーセルの意味、スライダー・スライドショーとの違い、使う/使わない判断表
  • CSS scroll-snap・自作 JS・Swiper の3通りを同じ画像5枚で作り、JS/CSS の量・初期表示・CLS・キーボード・スワイプ・属性を Chromium で実測した表
  • 自動再生の決まり(WCAG 2.2.2)と、画像が潰れる・ガタつく・端で戻る、の原因と直し方

2026年10月29日更新|Chromium 153・Swiper 12.2.0・Playwright 1.63 で実行確認

カルーセルは「1枚ずつ順番に見せる」部品なので、画面の中では次の図のように動きます。切り替えのきっかけは、利用者の操作(矢印・点・スワイプ・キーボード)と、自動再生の2つです。

flowchart TD
    S1[スライド1<br>表示中] -->|次へ・スワイプ<br>自動再生| S2[スライド2]
    S2 --> S3[スライド3…5]
    S3 -->|端まで行くと| E{ループする?}
    E -->|する| S1
    E -->|しない| STOP[端で止まる]

よく調べられることの答えを先にまとめます。

知りたいこと 答え 詳しい節
カルーセルとは(意味) 複数の内容を同じ場所で順番に切り替えて見せる UI。語源は回転木馬 カルーセルとは
スライダーとの違い ほぼ同じもの。呼び方の違いで、厳密な区別は無い カルーセルとは
カルーセル UI のメリット 場所の節約・大きく見せられる・動きで目を引く メリットとデメリット
デメリット 2枚目以降が見られない・重くなる・自動再生が読みづらい 「1枚目以外は見られない」
使うべきか 利用者が自分でめくる一覧・ギャラリーなら向く。必ず読ませたい情報には使わない 使う・使わない判断表
作り方 CSS scroll-snap(JS なし)・自作 JS・Swiper の3通り 3通りの作り方
どれが軽いか scroll-snap は CSS 792 バイト、Swiper は JS と CSS で約 170KB(gzip 約 46KB) 実測1:JS/CSS の量
自動再生してよいか 5秒を超えて動くなら「止める手段」が WCAG のレベル A で要る 自動再生の是非
画像が潰れる・ガタつく object-fit と width/height(aspect-ratio)の指定で直る よくある不具合

確認環境:Ubuntu 24.04.5 LTS の上で、Python 3.13.18 の http.server を 127.0.0.1:8104 に起動し、自分で作った3つのページ(CSS scroll-snap 版・自作 JS 版・Swiper 12.2.0 版)と同じ JPEG 画像5枚(1200×600 ピクセル、各 23〜24KB)を置きました。Swiper は npm で作業用のフォルダーに入れ、swiper-bundle.min.js と swiper-bundle.min.css をそのまま配信しています。表示は Chromium 153.0.8010.12(Playwright 1.63.0、Node.js 22.23.4)で開き、PC(幅 1280px)とスマホ相当(幅 390px・タッチあり)の2通り、回線は「制限なし」と、Chrome DevTools と同じ条件の「低速 4G 相当(下り 1.6Mbps・遅延 150ms・CPU 4倍遅く)」の2通りで測りました。初期表示の時間は Navigation Timing と Paint Timing、CLS と LCP は PerformanceObserver、キーボード・スワイプ・自動再生の挙動はページ内の値を読んで確かめています。WAI-ARIA の属性は W3C の APG「Carousel Pattern」、自動再生の決まりは WCAG 2.2 の原文、クリック率の数値は公開されている調査の原文で確かめました。図は mermaid 11.16.0 で描画を確かめています(確認日 2026年10月29日)。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「カルーセルとは|意味・使いどころ・3通りの作り方を実測で比較」

カルーセルとは(意味・語源・スライダーとの違い)

この節では、カルーセルという言葉の意味と、スライダー・スライドショーとの関係が分かります。

カルーセル(carousel)とは、Web サイトやアプリで、複数の画像・カード・バナーを同じ枠の中で順番に切り替えて見せる UI のことです。英語の carousel は「回転木馬(メリーゴーラウンド)」で、ぐるぐる回って次の馬が目の前に来る様子から名付けられました。語源の話はここまでで、以降は Web の部品としてのカルーセルを扱います。

利用者から見える要素は、だいたい次の4つです。

  • スライド:切り替わる1枚1枚。画像、画像+見出し、商品カードなど。
  • 矢印(前へ・次へ):1枚ずつ送るボタン。
  • インジケーター(点・番号):全部で何枚あり、今何枚目かを示す。点を押すとその枚へ飛べることが多い。
  • 自動再生:一定秒数で勝手に次へ進む仕組み。無いものもある。

スライダー・スライドショー・バナーとの違い

言葉 使われ方 カルーセルとの関係
スライダー 制作側がライブラリや実装を指して使うことが多い(Swiper・slick など) ほぼ同じもの。厳密な区別は無い
スライドショー 自動で流れる演出を指すことが多い(写真が次々に出る) 自動再生中心のカルーセル
バナー・ヒーロー画像 ページ上部の大きな画像1枚 カルーセルにせず1枚で固定する選択肢
カルーセル広告・カルーセル投稿 Meta・LINE・Google の広告、Instagram・X の投稿で、複数枚を横にめくる形式 同じ見せ方を広告・SNS の機能として提供したもの

この記事は Web サイトの部品としてのカルーセルが主題です。広告・SNS のカルーセルは次の節で触れるだけにします。

カルーセルが使われる場所(Web サイト・SNS・広告)

この節では、「カルーセル」という言葉がどの場面で出てくるかが分かります。

同じ「カルーセル」でも、Web サイトの部品、SNS の投稿形式、広告の形式の3つは、作る人も目的も違います。

1Web サイトの部品

トップページの最上部(ファーストビュー)、商品画像の切り替え、導入事例やお客様の声、関連記事の一覧。この記事で作り方と実測を扱うのはここ。

2SNS の投稿形式

Instagram・X・LinkedIn などで、複数枚の画像を横にめくる投稿。「1枚目で止まらせて、2枚目以降で説明する」構成が多い。作るのは画像で、コードは書かない。

3広告の形式

Meta 広告・LINE 広告・Google 広告などの「カルーセル広告」。1枚ごとに別のリンク先を付けられる。設定は各広告の管理画面で行う。

Web サイトで使う場合も、「商品を何枚も見比べたい」「写真を眺めたい」のように利用者が自分でめくる理由があるかが、後で出てくる判断の分かれ目になります。

カルーセル UI のメリットとデメリット

この節では、カルーセルを使うと何が良くなり、何が悪くなるのかが分かります。

メリットは「場所」、デメリットは「見られない・重い・読みづらい」です。検索上位の解説でも、挙げられている内容はほぼこの3対3に収まります。

メリット

限られた場所に複数の内容を置ける(特にスマホの縦長画面)

縮小せずに1枚ずつ大きく見せられる

動きがあると目に留まりやすい

デメリット

2枚目以降はほとんど見られない(次の節の数値)

ライブラリと画像で重くなり、初期表示が遅れる(実測1)

自動再生は読んでいる途中で消え、操作の邪魔になる(WCAG の決まり)

メリットは「作る側・載せる側」に効き、デメリットは「見る側」に効く、という非対称があります。社内の各部署が「自分のバナーもトップに載せたい」と言うと枚数が増えがちですが、増えた分だけ見られなくなるのがカルーセルです。

「1枚目以外はほとんど見られない」調査の数値

この節では、カルーセルの2枚目以降がどれだけ見られないのかを、公開されている調査の数値で確かめます。

よく引かれるのは、米ノートルダム大学の Web 担当だった Erik Runyon 氏が2013年1月に公開した「Carousel Interaction Stats」です。大学のトップページで、カルーセルの中身をクリックした訪問者は約1%、そのクリックのうち84%が1枚目に集中していました。同氏が併せて載せた他のサイトの数字も、次のとおりです(出典は末尾)。

1%カルーセルを押した訪問者ND.edu トップページ(2012年10月〜2013年1月)
84%そのうち1枚目のクリック2枚目以降は残りの16%を分け合う
8.8%自動再生ありのサイト1枚目40%・2枚目18%・最後の枚11%

13年前の1つの大学の数字なので、そのまま自分のサイトに当てはめることはできません。それでも「1枚目に重要な内容を置き、2枚目以降は見られない前提で作る」という設計の根拠としては、今もこの調査が引かれています。自分のサイトでは、GA4 のイベントやヒートマップで「何枚目まで操作されたか」を測ると、同じ形の数字が取れます。

カルーセルを使う・使わない判断表

この節では、自分のページにカルーセルを置くべきかどうかを、場面ごとに判断できます。

「利用者が自分でめくる理由があるか」と「全員に読ませたいか」の2つで決まります。

場面 判断 理由・代わり
商品ページの写真(正面・側面・使用例) 使う 見比べたい理由がある。サムネイル付きが望ましい
写真ギャラリー・導入事例の一覧 使う 眺める用途。自動再生はしない
スマホで横に並ぶカード(関連記事・おすすめ) 使う(scroll-snap) 横スクロールの一覧として自然。JS は要らない
トップページのファーストビュー 1枚に絞るのを先に検討 2枚目以降は約1%のさらに一部しか見ない。ヒーロー画像1枚+下にカードの並び
お知らせ・注意事項・キャンペーン条件 使わない 全員に読ませたい情報は隠さない。一覧(リスト)で縦に並べる
ナビゲーション・メニュー 使わない 動くメニューは押せない。固定の一覧にする
PC の広い画面で複数の訴求 使わない グリッドで全部並べれば、めくらなくても見える
  1. 1全員に読ませたい → カルーセルにしない縦に並べる。隠れた内容は読まれない
  2. 2並べれば全部見える → グリッドPC では 3〜4 列に並ぶなら、めくらせない
  3. 3スマホで横に流したい → CSS scroll-snapJS なし。指でめくれて、PC ではスクロールバーが出る
  4. 4矢印・点・ループ・自動再生が要る → 自作 JS か Swiper要件が少なければ自作(約 4KB)、多ければ Swiper(約 170KB)
  5. 5自動再生する → 止めるボタンを付け、ホバーと操作で止めるWCAG 2.2.2(レベル A)と APG の決まり

3通りの作り方(CSS scroll-snap・自作 JS・Swiper)

この節では、同じ画像5枚で作った3通りのカルーセルの、コードの要点が分かります。

3通りとも、HTML はリスト(ul・li)に画像を入れた同じ形で、違いは「送る仕組み」だけです。画像には width・height を付け、CSS で aspect-ratio: 2/1 と object-fit: cover を指定して、3通りを同じ条件にしています(この指定が無いときに何が起きるかは「よくある不具合」の節で実測します)。

A:CSS scroll-snap(JS なし)

横スクロールの入れ物に scroll-snap-type: x mandatory を付け、各スライドに scroll-snap-align: start を付けるだけです。指でめくると1枚ごとに止まり、PC ではスクロールバーとキーボードで送れます。点はページ内リンク(href="#s2")にしました。

<section class="cs" aria-roledescription="カルーセル" aria-label="おすすめの写真">
  <ul class="cs__track" tabindex="0" aria-label="横にスクロールできます">
    <li class="cs__slide" id="s1"><img src="img/1.jpg" width="1200" height="600" alt="写真1"></li>
    <li class="cs__slide" id="s2"><img src="img/2.jpg" width="1200" height="600" alt="写真2" loading="lazy"></li>
    …(5枚まで同じ)
  </ul>
  <nav class="cs__dots" aria-label="スライドを選ぶ"><a href="#s1">1</a><a href="#s2">2</a>…</nav>
</section>
.cs__track{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;scroll-behavior:smooth;list-style:none;margin:0;padding:0}
.cs__slide{flex:0 0 100%;scroll-snap-align:start;scroll-snap-stop:always}
.cs__slide img{display:block;width:100%;height:auto;aspect-ratio:2/1;object-fit:cover}
@media (prefers-reduced-motion:reduce){.cs__track{scroll-behavior:auto}}

scroll-snap の書き方の細部(余白・複数枚表示・スクロールバーの消し方)は、関連記事「CSS scroll-snapで横スクロールカルーセル|JSなしの完成版」で扱っています。この記事は入口として、3通りの比較に絞ります。

B:自作 JS(transform で送る)

スライドを横一列に並べ、transform: translateX(-100% × 枚数) で送ります。前へ・次へ・点・自動再生とその停止ボタン・矢印キー・スワイプを、約 90 行(3,225 バイト)で書きました。要点は次のとおりです。

function go(k) {
  i = (k + n) % n;                                  // 端で反対側へ回る
  track.style.transform = 'translateX(' + (-100 * i) + '%)';
  slides.forEach(function (s, k2) {
    var on = k2 === i;
    s.setAttribute('aria-hidden', on ? 'false' : 'true');
    if (on) { s.removeAttribute('inert'); } else { s.setAttribute('inert', ''); }
    dots.children[k2].setAttribute('aria-selected', on ? 'true' : 'false');
  });
}
function start() {                                   // 自動再生(5秒)
  if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) { return; }
  timer = setInterval(function () { go(i + 1); }, 5000);
}
root.addEventListener('mouseenter', pause);         // ホバーで止める
root.addEventListener('focusin', pause);            // フォーカスが入ったら止める
root.addEventListener('keydown', function (e) {    // 矢印キー
  if (e.key === 'ArrowRight') { go(i + 1); stop(); }
  if (e.key === 'ArrowLeft')  { go(i - 1); stop(); }
});

C:Swiper 12

npm の swiper(12.2.0)の bundle 版を読み込み、ループ・キーボード・自動再生・矢印・点を設定で有効にしました。アクセシビリティ用の属性は Swiper の a11y モジュールが自動で付けます。

new Swiper('.swiper', {
  loop: true,
  keyboard: { enabled: true },
  autoplay: { delay: 5000, pauseOnMouseEnter: true },
  navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev' },
  pagination: { el: '.swiper-pagination', clickable: true },
  a11y: { prevSlideMessage: '前のスライド', nextSlideMessage: '次のスライド' }
});

Swiper のオプション全体・React や Vue での使い方・動かないときの原因は、関連記事「Swiperの使い方|オプション早見表・React/Vue・動かない原因を実演」で扱っています。

実測1:送られる JS/CSS の量と初期表示の時間

この節では、3通りで利用者に送られるファイルの量と、ページが表示されるまでの時間の違いが分かります。

scroll-snap は CSS 792 バイトだけ、自作 JS は約 4KB、Swiper は約 170KB(gzip で約 46KB)でした。画像は3通りとも同じで、初期表示までに読み込まれたのは5枚中2〜3枚です(loading="lazy" を2枚目以降に付けたため)。

作り方 JS(バイト) CSS(バイト) 合計(gzip 後)
A:CSS scroll-snap 0 792 792(451)
B:自作 JS 3,225 758 3,983(1,541)
C:Swiper 12 bundle 155,297 14,609 169,906(46,619)

Swiper は、使うモジュールだけを ES Modules で取り込めば(swiper.min.js は 68,966 バイト)小さくなります。次は初期表示の時間です。回線に制限が無いと差は数十ミリ秒ですが、「低速 4G 相当」にすると、JS を読み終えるまで DOMContentLoaded が待たされる差が出ました。

条件 指標(ms) A:scroll-snap B:自作 JS C:Swiper
制限なし・PC DOMContentLoaded 26 58 93
制限なし・PC LCP(最大の画像の表示) 64 104 116
低速 4G・PC DOMContentLoaded 245 505 1,599
低速 4G・PC FCP(最初の描画) 444 444 656
低速 4G・PC LCP 520 544 712
低速 4G・スマホ幅 DOMContentLoaded 326 462 1,709
低速 4G・スマホ幅 LCP 628 540 700

Swiper の DOMContentLoaded が約 1.6 秒になったのは、script を body の末尾に置いた素の読み込みで、155KB の JS を下り 1.6Mbps で受け取る時間がそのまま乗ったためです。defer と gzip 配信にすれば縮みますが、「カルーセルのために 1 枚目の画像より大きいファイルを送る」構図は変わりません。

実測2:CLS(表示のガタつき)と画像の寸法

この節では、カルーセルが原因で起きる「表示のガタつき(CLS)」を、寸法の指定あり・なしで比べた結果が分かります。

画像に width・height(または aspect-ratio)を付けた3通りはいずれも CLS 0、外した scroll-snap 版は低速 4G で 0.0501 でした。画像が届くまで高さ 0 だった枠が、届いた瞬間に 480px 分ふくらみ、下の本文が押し下げられたのが原因です。

ページ 画像の寸法指定 CLS(低速 4G) 何が起きたか
A・B・C width/height+aspect-ratio 0 読み込み前から高さが確保されている
A から寸法を外した版 なし 0.0501(362ms 時点で1回) 画像が届いた瞬間に下の本文が 480px 下がった
B の最初の版 あり(点を JS で後から生成) 0.0018 JS が点を挿入した 70ms 時点で下の本文が 44px 下がった
B(点の枠に min-height:44px) あり 0 点の枠の高さを CSS で先に確保

B の 0.0018 は小さいものの、「JS が後から部品を挿入すると、その分だけガタつく」という、自作・ライブラリを問わず起きる形です。Swiper でも、矢印や点の要素を JS で生成する設定にすると同じことが起きるので、HTML に先に置いて高さを持たせておきます。画像の寸法と object-fit の組み合わせは、関連記事「CSS object-fit・aspect-ratio|画像トリミング5パターン」で扱っています。

実測3:キーボード操作・スワイプ・自動再生・端での挙動

この節では、3通りのカルーセルを、マウス以外の方法で操作したときに何が起きるかが分かります。

3通りとも、Tab キー1回でカルーセルに入り、→キーで次のスライドへ進み、スマホ幅の指の動き(タッチ)で1枚送れました。違いが出たのは、自動再生の止まり方と、端まで行ったときの動きです。

確かめたこと A:scroll-snap B:自作 JS C:Swiper
Tab で最初に止まる場所 スクロールの枠(tabindex=0) 「前のスライド」ボタン 「前のスライド」ボタン
Tab の停止数(枠の中) 6(枠+点5) 8(矢印2+停止1+点5) 7(矢印2+点5)
→キーで次へ 進む(枠にフォーカスがある時だけ) 進む 進む(画面内にある時)
タッチで左へ払う(幅 390px) 1→2 1→2 1→2
5.6 秒放置(自動再生) 動かない(機能なし) 1→2 1→2
マウスを乗せて 5.6 秒 ― 止まる(1のまま) 止まる(1のまま)
「動きを減らす」設定で 5.6 秒 ― 止まる(自作で判定) 1→2(設定を見ない)
最後の枚で「次へ」 端で止まる 1へ戻る(巻き戻しが見える) 1へ進む(ループ)

「最後の枚で次へ」の違いを、もう少し見ます。B は translateX(-400%) から 0 へ 0.4 秒で戻るので、途中(150ms 時点)の値は matrix(1, 0, 0, 1, -1628.44, 0)、つまり4枚分を逆走している最中でした。これが「無限ループのはずが、端で巻き戻って見える」不具合の正体です。C は端に来ると、Swiper が DOM の先頭の li(写真1)を末尾へ動かし(並びが「2,3,4,5,1」になった)、前へ進む動きのまま1枚目に着きました。A はループしないので、端では止まります。

もう1つ、A の点をページ内リンクにした副作用があります。カルーセルの上に 600px の余白を置いた状態で「3」のリンクを押すと、横に3枚目へ進むと同時に window.scrollY が 0 から 488 に変わり、ページ全体も縦に動きました。href="#id" はその要素が見える位置までページ全体をスクロールするためで、点を使うなら JS で scrollIntoView({ inline: 'start', block: 'nearest' }) を呼ぶか、点を付けずにスクロールバーに任せます。

実測4:スクリーンリーダー向けの属性(WAI-ARIA APG)

この節では、W3C の APG「Carousel Pattern」が推奨する属性と、3通りで実際に付いた属性の対応が分かります。

APG の推奨は、入れ物に aria-roledescription="carousel" とラベル、各スライドに role="group"・aria-roledescription="slide"・「3 of 10」のような名前、自動回転中は aria-live="off"、停止中は polite、ボタンはネイティブの button、です。3通りのページから、実際に付いていた属性を読み出しました。

要素 A:scroll-snap(手書き) B:自作 JS(手書き) C:Swiper の a11y
入れ物 aria-roledescription・aria-label aria-roledescription・aria-label aria-label(自分で付けた)のみ
スライド なし role=group・aria-roledescription=スライド・aria-label="1 / 5"・aria-hidden・inert role=group・aria-label="1 / 5"
ライブリージョン なし ul に aria-live=polite wrapper に aria-live=off、別に aria-live=assertive の通知用 span(操作後も空のまま)
矢印 なし button・aria-label span role=button tabindex=0・aria-label(設定した日本語)
点 a(1〜5の文字) button role=tab・aria-label・aria-selected span role=button tabindex=0・aria-label="Go to slide 1"(既定は英語)・aria-current

Swiper の a11y モジュールは、矢印と点に role="button" と tabindex="0" を付けて span をボタン扱いにし、点のラベルは英語の既定値のままでした。日本語サイトでは a11y.paginationBulletMessage: 'スライド {{index}} へ' のように設定します。また、APG は自動再生の停止ボタンについて「ラベルを『Stop slide rotation』『Start slide rotation』のように切り替え、aria-pressed は付けない」としています。B の停止ボタンは aria-pressed を付けていたので、APG に合わせるならラベルの切り替えだけにします。

WCAG 2.2 の達成基準を一覧で確かめる手順は、関連記事「WCAG 2.2チェックリスト|A・AA全55項目と確認方法・axe検査手順」で扱っています。

自動再生の是非(WCAG 2.2.2「一時停止、停止、非表示」)

この節では、カルーセルを自動で動かしてよいのか、動かすなら何が要るのかが、WCAG の原文で分かります。

WCAG 2.2 の達成基準 2.2.2(レベル A)は、自動で始まり、5 秒を超えて続き、他の内容と並んで表示される「動く・点滅する・スクロールする情報」には、利用者が一時停止・停止・非表示にできる仕組みを求めています。原文は次のとおりです。

For any moving, blinking or scrolling information that (1) starts automatically, (2) lasts more than five seconds, and (3) is presented in parallel with other content, there is a mechanism for the user to pause, stop, or hide it unless the movement, blinking, or scrolling is part of an activity where it is essential

自動再生のカルーセルは、この3条件を全部満たします。つまり「レベル A を満たすには、止める手段が必ず要る」ということです。APG はさらに、マウスが乗っている間とキーボードフォーカスが中にある間は回転を止め、停止ボタンを Tab 順の最初に置く、としています。

自動再生の作り方

やってはいけない3秒で切り替わり、止めるボタンが無く、マウスを乗せても動き続ける。読んでいる途中で文章が消える
→
代わりに5秒以上の間隔、「自動再生を止める」ボタンを先頭に、ホバー・フォーカス・操作で止める、「動きを減らす」設定(prefers-reduced-motion)なら最初から動かさない

実測では、Swiper 12 は prefers-reduced-motion を見ずに動いたので、自分で判定して autoplay を止める

Swiper で「動きを減らす」設定に合わせるには、初期化の前に window.matchMedia('(prefers-reduced-motion: reduce)').matches を見て、真なら autoplay を渡さない(または swiper.autoplay.stop() を呼ぶ)形になります。

スマホでのカルーセル(スワイプ・幅・画像の大きさ)

幅 390px では、3通りとも 1200×600 の画像が 358×179 ピクセルに縮んで表示され、指で左へ払うと 1 枚送れました。見た目は同じでも、裏で送っている画像は 1200px のままなので、スマホ向けに小さい画像を用意する srcset・sizes の出番です(関連記事「srcset・sizesの使い方|picture併用とDevToolsでの検証」で扱っています)。

  • scroll-snap はスワイプが「ただのスクロール」なので、慣性・引っかかり・戻りが OS のスクロールと同じ感触になります。自作 JS は touchstart・touchend の差 40px で判定した簡易版、Swiper は指に追従して動きます。
  • 縦スクロールを邪魔しないこと。自作 JS では touch-action: pan-y を指定し、縦の指の動きはブラウザに渡しました。これが無いと、カルーセルの上で縦にスクロールできなくなることがあります。
  • 矢印はスマホでは押しにくいので、点かスワイプに頼ります。点は 44×44px 以上にしました(3通りとも)。
  • 画像は2枚目以降を loading="lazy" にしました。制限なしでは 1.5 秒後に5枚中4枚、低速 4G では 3 秒後に2枚が読み込まれていました。Chromium は画面外でも近い画像を先読みするため、「見えるまで一切読まない」わけではありません。

よくある不具合と直し方(画像が潰れる・ガタつく・端で戻る)

この節では、カルーセルで起きやすい不具合を手元で再現し、原因と直し方が分かります。

不具合の多くは「画像の寸法」「初期化のタイミング」「ループの作り」の3つに集約されます。

症状 手元で再現した状態 原因 直し方
画像が横に潰れる・伸びる 高さ 240px 固定で、表示 960×240(比 4.00)、元画像は比 2.00、object-fit は fill 枠の比と画像の比が違い、既定の object-fit: fill で引き伸ばされた object-fit: cover(切り抜く)か contain(余白を出す)。比をそろえるなら aspect-ratio
読み込み時にガタつく 寸法なしで CLS 0.0501、本文が 480px 下がった 画像が届くまで高さ 0 width・height 属性か aspect-ratio。JS で作る点や矢印は枠の高さを先に確保
表示したら全スライドが縦に並ぶ・幅 0 display:none の中で Swiper を初期化すると、初期化直後は width が null、slidesGrid が [0, NaN, NaN, …] 隠れた要素は幅が測れない Swiper 12 では表示後に resizeObserver が自動で再計算して直った。確実にするなら表示した直後に swiper.update()
端で巻き戻って見える 自作 JS で 5→1 のとき 4 枚分を逆走(150ms 時点で -1628px) translateX を 0 に戻す遷移がそのまま見える 端ではアニメーションを切る、または先頭と末尾の複製を置いて位置を差し替える(Swiper はこの方式)
点を押すとページが飛ぶ scroll-snap 版の href="#s3" で scrollY が 0→488 ページ内リンクはページ全体をスクロールする JS で scrollIntoView({ inline: 'start', block: 'nearest' })
縦にスクロールできない 自作 JS で touch-action なし 指の動きをカルーセルが全部受け取る touch-action: pan-y
キーボードで送れない scroll-snap 版で枠にフォーカスが無いと →キーは無反応(scrollLeft 0 のまま) スクロールの枠がフォーカスを受けない 枠に tabindex="0" と aria-label。Swiper は keyboard モジュールを有効に

Swiper の「ループ時にスライド数が足りない」件も試しました。5枚で slidesPerView: 3・loop: true にしても、12.2.0 ではコンソールに警告は出ず、「次へ」を5回押すと realIndex が 0 に戻ってループしました。以前の版で出ていた警告文は、版によって挙動が違うため、手元の版で確かめるのが確実です。

カルーセルの代わりになる見せ方

この節では、「カルーセルにしない」と決めたときに、何に置き換えるかが分かります。

置き換え先は、ヒーロー画像1枚、グリッド、縦の一覧、動画、タブ、アコーディオンのどれかです。「複数の訴求を1か所に」という要望に対して、カルーセル以外の答えを先に持っておくと、枚数が増え続けるのを止められます。

1ヒーロー画像1枚+下にカード

最上部は最も伝えたい1枚に絞り、残りは下にカードで並べる。全部が最初から見え、CLS もライブラリも増えない。

2グリッド(PC)+横スクロール(スマホ)

PC では 3〜4 列に並べ、スマホでは同じ HTML を scroll-snap で横に流す。CSS だけで切り替えられる。

3タブ・アコーディオン

利用者が選んで開く形。自動で切り替わらないので、読んでいる途中で消えない。見出しが一覧になる利点もある。

商品写真のように「同じものの別の面」を見せる用途は、カルーセルのままで問題ありません。置き換えを考えるのは、「別々の訴求を1つの枠に詰めている」ときです。

公開前のチェックリスト

実測で差が出た項目を、そのまま確認項目にしました。

  • 11枚目に最も重要な内容がある2枚目以降は見られない前提。順番は優先度順
  • 2画像に width・height(または aspect-ratio)と object-fit があるCLS 0 と、潰れない表示
  • 3Tab と →キーだけで全スライドに行ける枠に tabindex、または矢印ボタン。ボタンはネイティブの button
  • 4自動再生なら、止めるボタン・ホバーとフォーカスで停止・5秒以上WCAG 2.2.2(レベル A)。prefers-reduced-motion も見る
  • 5入れ物とスライドに名前が付いているaria-roledescription・aria-label・role=group。ライブラリの既定の英語ラベルを日本語に
  • 6低速回線で初期表示を測ったDevTools の低速 4G で、JS がファーストビューを遅らせていないか
  • 7スマホで縦スクロールとスワイプの両方が動くtouch-action: pan-y。点は 44px 以上

よくある質問

Q. カルーセルとは何ですか? A. 複数の画像や内容を同じ枠の中で順番に切り替えて見せる UI です。矢印・点・スワイプ・自動再生で切り替えます。語源は回転木馬(carousel)です。

Q. カルーセルとスライダーの違いは何ですか? A. ほぼ同じものを指し、厳密な区別はありません。制作側はライブラリ名にちなんで「スライダー」と呼ぶことが多く、自動で流れる演出は「スライドショー」と呼ばれがちです。

Q. カルーセルは SEO に悪いですか? A. カルーセルそのものが順位を下げるわけではありません。影響するのは、JS と画像で初期表示(LCP)が遅れること、寸法の指定が無くてガタつく(CLS)ことです。手元の実測では、寸法を付けた3通りはいずれも CLS 0 でした。

Q. 自動再生は付けるべきですか? A. 付けるなら、WCAG 2.2.2(レベル A)に従って止める手段が要ります。5 秒以上の間隔、停止ボタン、ホバーとフォーカスでの停止が目安です。写真ギャラリーや商品画像では、自動再生を付けない方が操作しやすくなります。

Q. 2枚目以降は本当に見られないのですか? A. 2013年の Erik Runyon 氏の調査では、大学トップページでカルーセルを押した訪問者は約1%、そのうち84%が1枚目でした。サイトによって違うので、自分のサイトでは GA4 のイベントで「何枚目まで操作されたか」を測ります。

Q. JS なしでカルーセルは作れますか? A. 作れます。CSS の scroll-snap で、指でめくれて PC ではスクロールバーとキーボードで送れるものが CSS 792 バイトでできました。矢印・点・ループ・自動再生が要るときは JS が必要です。

Q. Swiper と自作、どちらにすべきですか? A. 要件が「矢印と点だけ」なら自作(約 4KB)で間に合い、ループ・複数枚表示・サムネイル連動・縦方向・エフェクトなどが要るなら Swiper(bundle で約 170KB、gzip 約 46KB)が早道です。Swiper は必要なモジュールだけを ES Modules で取り込むと小さくなります。

Q. 画像が潰れて表示されるのはなぜですか? A. 枠の縦横比と画像の縦横比が違うのに、object-fit が既定の fill のままだからです。手元では高さ固定の枠で 1200×600 の画像が 960×240 に引き伸ばされました。object-fit: cover か contain を指定します。

Q. 何枚まで入れてよいですか? A. 決まりはありませんが、3〜5枚が目安としてよく挙げられます。実測の数値から言えるのは「枚数を増やすほど、1枚あたりが見られる確率は下がる」ことです。

Q. スクリーンリーダーには何が必要ですか? A. 入れ物に aria-roledescription="carousel" とラベル、スライドに role="group" と「1 / 5」のような名前、ネイティブの button、自動回転中は aria-live="off"、停止中は polite、が W3C APG の推奨です。

Q. カルーセル広告とは何ですか? A. Meta・LINE・Google などの広告で、複数枚の画像やカードを横にめくる形式です。1枚ごとに別のリンク先を設定できます。Web サイトの部品としてのカルーセルとは、作る場所も設定方法も別です。

まとめ

  • カルーセルとは、複数の内容を同じ枠で順番に切り替えて見せる UI。スライダー・スライドショーとの厳密な区別は無い。
  • 場所を節約できる一方で、2枚目以降はほとんど見られない(約1%のうち84%が1枚目という調査)。全員に読ませたい情報には使わず、1枚目に最重要の内容を置く。
  • 作り方は CSS scroll-snap(CSS 792 バイト・JS なし)、自作 JS(約 4KB)、Swiper 12(約 170KB、gzip 約 46KB)の3通り。低速 4G では Swiper の DOMContentLoaded が約 1.6 秒、他の2つは 0.25〜0.5 秒だった。
  • 画像に width・height(aspect-ratio)と object-fit を付ければ3通りとも CLS 0。外すと 0.05 のガタつきと、潰れた画像になった。
  • 自動再生には止める手段が要る(WCAG 2.2.2 レベル A)。Swiper 12 は prefers-reduced-motion を見ないので、自分で判定して止める。端での「巻き戻り」は translateX の遷移が見えているだけで、複製スライドで差し替える方式なら起きない。

次に読むとよい記事です。JS なしで作るなら「CSS scroll-snapで横スクロールカルーセル|JSなしの完成版」、Swiper のオプションを調べるなら「Swiperの使い方|オプション早見表・React/Vue・動かない原因を実演」、画像の切り抜きと縦横比は「CSS object-fit・aspect-ratio|画像トリミング5パターン」、アクセシビリティの確認手順は「WCAG 2.2チェックリスト|A・AA全55項目と確認方法・axe検査手順」が続きです。

参考・出典

確認日はいずれも 2026年10月29日です。

  • W3C「WCAG 2.2」2.2.2 Pause, Stop, Hide:https://www.w3.org/TR/WCAG22/#pause-stop-hide
  • W3C WAI「ARIA Authoring Practices Guide: Carousel Pattern」:https://www.w3.org/WAI/ARIA/apg/patterns/carousel/
  • Erik Runyon「Carousel Interaction Stats」(2013年1月22日):https://erikrunyon.com/2013/01/carousel-interaction-stats/
  • MDN「CSS スクロールスナップ」:https://developer.mozilla.org/ja/docs/Web/CSS/CSS_scroll_snap
  • MDN「object-fit」:https://developer.mozilla.org/ja/docs/Web/CSS/object-fit
  • MDN「aspect-ratio」:https://developer.mozilla.org/ja/docs/Web/CSS/aspect-ratio
  • MDN「prefers-reduced-motion」:https://developer.mozilla.org/ja/docs/Web/CSS/@media/prefers-reduced-motion
  • web.dev「Cumulative Layout Shift (CLS)」:https://web.dev/articles/cls
  • Swiper「Swiper API」(Autoplay・Keyboard・A11y・Loop のパラメーター):https://swiperjs.com/swiper-api
  • Swiper「Get Started」(npm・ES Modules での読み込み):https://swiperjs.com/get-started

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「カルーセルとは|意味・使いどころ・3通りの作り方を実測で比較」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ
参加受付中

AI駆動開発、 無料セミナー