10. Splideスライダー実装

この章では、Splideを使ったスライダー実装を学びます。

スライダーはWeb制作でよく登場します。メインビジュアル、お客様の声、実績一覧、カード一覧、バナーなど、さまざまな場面で使われます。

ただし、スライダーは見た目以上に複雑です。ドラッグ操作、タッチ操作、ループ、ページネーション、矢印、アクセシビリティ、レスポンシブ対応などを自作で安全に作るのは大変です。

そのため実務では、SplideやSwiperなどのライブラリを使うことが多いです。

スライダーを使うべき場面

まず、スライダーが本当に必要かを考えます。

スライダーは便利ですが、何でもスライダーにすればよいわけではありません。

場面判断
メインビジュアルを複数枚見せたい要件次第で使う
お客様の声を横に流したい使うことが多い
実績カードをスマホで横スクロールさせたい使うことがある
重要なCTAを複数枚に分けたい慎重に判断する
必ず読んでほしい情報を隠す避けた方がよい

スライダーは、2枚目以降が見られないこともあります。

重要な情報をスライダーの後ろに隠すと、ユーザーに届かない可能性があります。

Splideの導入

npmを使う環境では、Splideをインストールして読み込みます。

npm
npm install @splidejs/splide
JavaScript
import Splide from "@splidejs/splide";
import "@splidejs/splide/css";

静的なHTML制作では、CDNで読み込む場合もあります。

CDN
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@splidejs/splide/dist/css/splide.min.css" />
<script src="https://cdn.jsdelivr.net/npm/@splidejs/splide/dist/js/splide.min.js"></script>

この章では、Splideが使える状態になっている前提でコードを見ていきます。

基本のHTML構造

Splideには、決まったHTML構造があります。

HTML
<section class="splide js-main-slider" aria-label="メインビジュアル">
    <div class="splide__track">
        <ul class="splide__list">
            <li class="splide__slide">
                <img src="/images/slide-1.jpg" alt="サービス紹介1" />
            </li>
            <li class="splide__slide">
                <img src="/images/slide-2.jpg" alt="サービス紹介2" />
            </li>
            <li class="splide__slide">
                <img src="/images/slide-3.jpg" alt="サービス紹介3" />
            </li>
        </ul>
    </div>
</section>

重要なのは、次のクラス名です。

クラス役割
.splideスライダー全体
.splide__trackスライドが動く領域
.splide__listスライドのリスト
.splide__slide各スライド

これらのクラスはSplideが内部で使います。

自分のCSS用クラスやJavaScript用クラスは、追加で付けるようにします。

実務でのクラス例
<section class="splide main-slider js-main-slider" aria-label="メインビジュアル">
</section>

基本の初期化

Splideは、対象要素を指定してインスタンスを作り、mountで起動します。

基本の初期化
const mainSlider = document.querySelector(".js-main-slider");

if (mainSlider) {
    const splide = new Splide(mainSlider);
    splide.mount();
}

対象要素がないページでエラーにならないよう、ガード処理を入れています。

オプション設定

Splideでは、第2引数にオプションを渡します。

オプション設定
const splide = new Splide(mainSlider, {
    type: "loop",
    perPage: 1,
    gap: "24px",
    autoplay: true,
});

splide.mount();

オプションはオブジェクトで指定します。

2章で学んだオブジェクトの形が、ここでそのまま出てきます。

よく使うオプション

Web制作でよく使うオプションを見ていきます。

オプション役割
typeスライダーの種類
perPage1画面に表示する枚数
perMove1回で移動する枚数
gapスライド間の余白
autoplay自動再生
interval自動再生の間隔
speed移動速度
arrows矢印の有無
paginationページネーションの有無
breakpoints画面幅ごとの設定

type

typeでは、スライダーの動き方を指定します。

type
new Splide(".js-slider", {
    type: "loop",
}).mount();

loopにすると、最後のスライドから最初のスライドへループします。

シンプルなスライダーでは、typeを指定しない場合もあります。

perPageとgap

perPageは、1画面に表示するスライド数です。

gapは、スライド間の余白です。

カードスライダー
new Splide(".js-card-slider", {
    perPage: 3,
    gap: "24px",
}).mount();

カード型のスライダーではよく使います。

breakpoints

breakpointsを使うと、画面幅ごとに設定を変えられます。

breakpoints
new Splide(".js-card-slider", {
    perPage: 3,
    gap: "24px",
    breakpoints: {
        1024: {
            perPage: 2,
        },
        768: {
            perPage: 1,
            gap: "16px",
        },
    },
}).mount();

この例では、通常は3枚、1024px以下で2枚、768px以下で1枚表示にしています。

autoplay

autoplaytrueにすると、自動再生できます。

autoplay
new Splide(".js-main-slider", {
    type: "loop",
    autoplay: true,
    interval: 4000,
    speed: 800,
}).mount();

ただし、自動再生は注意が必要です。

ユーザーが読んでいる途中に勝手に切り替わると、情報を追いにくくなります。

arrowsとpagination

矢印やページネーションの表示を切り替えられます。

矢印とページネーション
new Splide(".js-slider", {
    arrows: true,
    pagination: true,
}).mount();

デザインによっては、矢印だけ表示し、ページネーションを非表示にすることもあります。

ページネーションを非表示
new Splide(".js-slider", {
    arrows: true,
    pagination: false,
}).mount();

複数スライダーを初期化する

ページ内に同じ種類のスライダーが複数ある場合は、querySelectorAllでまとめて初期化します。

HTML
<section class="splide js-card-slider" aria-label="実績スライダー"></section>
<section class="splide js-card-slider" aria-label="お客様の声スライダー"></section>
複数初期化
const cardSliders = document.querySelectorAll(".js-card-slider");

cardSliders.forEach((slider) => {
    new Splide(slider, {
        perPage: 3,
        gap: "24px",
        breakpoints: {
            768: {
                perPage: 1,
            },
        },
    }).mount();
});

メインビジュアルスライダー

メインビジュアルでは、1枚ずつ表示し、自動再生するパターンがよくあります。

メインビジュアル
const mainSlider = document.querySelector(".js-main-slider");

if (mainSlider) {
    new Splide(mainSlider, {
        type: "fade",
        rewind: true,
        autoplay: true,
        interval: 5000,
        speed: 1000,
        arrows: false,
        pagination: true,
    }).mount();
}

type: "fade"はフェード切り替えです。

rewind: trueは、最後まで行った後に最初へ戻る設定です。

カードスライダー

カードスライダーでは、PCで複数枚、スマホで1枚にすることが多いです。

カードスライダー
const cardSliders = document.querySelectorAll(".js-card-slider");

cardSliders.forEach((slider) => {
    new Splide(slider, {
        perPage: 3,
        perMove: 1,
        gap: "24px",
        arrows: true,
        pagination: false,
        breakpoints: {
            1024: {
                perPage: 2,
            },
            768: {
                perPage: 1,
                gap: "16px",
                pagination: true,
            },
        },
    }).mount();
});

PCとスマホで、矢印やページネーションの要否が変わることもあります。

PCはグリッド、スマホだけスライダー

実務では、PCではカードをグリッド表示し、スマホだけスライダーにしたいことがあります。

この場合は、画面幅に応じてSplideを生成、破棄する必要があります。

SPのみスライダー
const sliderElement = document.querySelector(".js-sp-slider");
const mediaQuery = window.matchMedia("(max-width: 768px)");
let splide;

function switchSlider() {
    if (!sliderElement) {
        return;
    }

    if (mediaQuery.matches) {
        if (!splide) {
            splide = new Splide(sliderElement, {
                perPage: 1,
                gap: "16px",
                pagination: true,
            });

            splide.mount();
        }
    } else if (splide) {
        splide.destroy();
        splide = undefined;
    }
}

switchSlider();
mediaQuery.addEventListener("change", switchSlider);

PCではCSSグリッドで見せ、スマホ幅になった時だけSplideを有効にする考え方です。

サムネイル付きスライダー

商品画像や実績画像では、メインスライダーとサムネイルを連動させることがあります。

HTML
<section class="splide js-main-gallery" aria-label="メイン画像"></section>
<section class="splide js-thumbnail-gallery" aria-label="サムネイル"></section>
サムネイル連動
const mainGallery = new Splide(".js-main-gallery", {
    type: "fade",
    rewind: true,
    pagination: false,
    arrows: false,
});

const thumbnailGallery = new Splide(".js-thumbnail-gallery", {
    fixedWidth: 96,
    fixedHeight: 64,
    gap: "8px",
    rewind: true,
    pagination: false,
    isNavigation: true,
});

mainGallery.sync(thumbnailGallery);
mainGallery.mount();
thumbnailGallery.mount();

サムネイル付きは便利ですが、画像サイズ、フォーカス、スマホ表示を丁寧に確認する必要があります。

現在のスライド番号を表示する

現在のスライド番号を表示したい場合があります。

HTML
<section class="splide js-count-slider" aria-label="実績スライダー"></section>
<p><span class="js-current-slide">1</span> / <span class="js-total-slide">3</span></p>
スライド番号
const sliderElement = document.querySelector(".js-count-slider");
const currentText = document.querySelector(".js-current-slide");
const totalText = document.querySelector(".js-total-slide");

if (sliderElement && currentText && totalText) {
    const splide = new Splide(sliderElement);

    splide.on("mounted move", () => {
        currentText.textContent = String(splide.index + 1);
        totalText.textContent = String(splide.length);
    });

    splide.mount();
}

Splideのイベントを使うと、移動時に表示を更新できます。

CSSカスタマイズ

Splideの矢印やページネーションはCSSでカスタマイズできます。

矢印のカスタマイズ
.splide__arrow {
    width: 44px;
    height: 44px;
    background: #ffffff;
    border: 1px solid #d8dde8;
}

.splide__arrow svg {
    fill: #202124;
}
ページネーションのカスタマイズ
.splide__pagination__page {
    width: 8px;
    height: 8px;
    background: #c8ced8;
}

.splide__pagination__page.is-active {
    background: #007f68;
}

アクセシビリティの注意点

スライダーは、アクセシビリティ面で注意が必要なUIです。

スライダーを入れるだけで満足せず、ユーザーが情報にアクセスできるか確認しましょう。

よくある失敗

Splide実装でよくある失敗を整理しておきます。

  • .splide__track.splide__listなど、必要なHTML構造が足りない
  • 対象要素がないページでnew Splideしてエラーになる
  • 複数スライダーなのに、最初の1つしか初期化していない
  • PCとスマホの表示枚数がデザインと合っていない
  • 自動再生が速すぎて内容を読めない
  • 画像の高さが揃わず、スライダーの高さがガタつく
  • SPのみスライダーで、破棄後のPCレイアウトが崩れる
  • ライブラリCSSを読み込んでいない

スライダーは、動いたように見えても細かい確認が必要です。

特にスマホのタッチ操作と、画像読み込み後のレイアウトは必ず確認しましょう。

この章のまとめ

この章では、Splideを使ったスライダー実装を学びました。

  • スライダーは便利だが、重要情報を隠さないようにする
  • Splideには決まったHTML構造がある
  • new Splide(...).mount()で初期化する
  • オプションはオブジェクトで指定する
  • perPagegapbreakpointsはカードスライダーでよく使う
  • 複数設置ではquerySelectorAllでまとめて初期化する
  • SPのみスライダーでは、生成と破棄を考える
  • 自動再生、アクセシビリティ、スマホ操作を必ず確認する

次の章では、保守しやすいJavaScript設計を学びます。ここまで作ってきたUIを、案件で使い回しやすい形へ整理していきます。