多機能スライダーSwiperの機能を紹介します

Swiper アイキャッチ

Swiperは、jQuery不要の多機能なスライダープラグインです。

かんたんに印象的なエフェクトやスライドショー機能を実装することができます。
また、細かいパラメータや関数が用意されていて作り込む系のスライドショーになっています。

今回は、多機能スライダー「Swiper ver.9」の機能を紹介します。
また、仕事で使いそうなサンプルコードを多めに用意しました。

Swiperの主な機能について

Swiperは非常に多機能です。
公式ページ)Swiper - The Most Modern Mobile Touch Slider

機能一覧は、Swiper公式のデモページが見やすくまとまっています。
特徴的な機能は

  • トランジション時のエフェクトが豊富
  • ページネーション(通常スライドショー下にあるドット)の種類が豊富
  • 縦スライダー(Vertical)、多段に並べる(Grid)、スライダーの入れ子(Nested)
  • スクロール方法が多様(Freemode、Grab cursor)
  • ズーム機能(Zoom)

ループ、オートプレイ、サムネイルとメインスライダーとの連動、スライド高さ調整、ブレイクポイントにも対応しており、基本的な機能も備わっています。

作り込みが必要な時は「Swiper API」のマニュアルを確認します。
かなり細かい設定やイベントによる実行が可能です。この点もSwiperの特徴です。

Swiperで必要な基本コード

公式の「Getting Started With Swiper」に使い方が記載してあります。
プラグインを読み込んで、スライド部分のHTMLを書いて、Swiper(JavaScript)を実行する流れです。

プラグイン

プラグイン

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@9/swiper-bundle.min.css"/>
<script src="https://cdn.jsdelivr.net/npm/swiper@9/swiper-bundle.min.js"></script>

HTML

下例のように、swiperクラスに入れ子にして配置します。

HTML

<!-- Slider main container -->
<div class="swiper">
  <!-- Additional required wrapper -->
  <div class="swiper-wrapper">
    <!-- Slides -->
    <div class="swiper-slide">Slide 1</div>
    <div class="swiper-slide">Slide 2</div>
    <div class="swiper-slide">Slide 3</div>
    ...
  </div>
  <!-- If we need pagination -->
  <div class="swiper-pagination"></div>
  <!-- If we need navigation buttons -->
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>
  <!-- If we need scrollbar -->
  <div class="swiper-scrollbar"></div>
</div>

swiperswiper-wrapperswiper-slideのクラス名は、基本的にそのままで使います(position: relative; overflow: hidden; などの必要なスタイルが入っているため)。
これらのクラス名を変更する場合はパラメーター(containerModifierClass、wrapperClass、slideClass)を使用します。

11-19行目の、ページネーション(ドット)、ナビゲーション(矢印)、スクロールバー(位置表示の線)は必要な場合に書きます。


さらに、CSSがあるとレイアウトが整います。
設置場所によってはナビゲーションボタンやページネーションの位置がずれます。
以下の3つが必要になる場合があります。

CSS

.swiper {
  max-width: 1200px; /* スライドの最大幅 */
}
.swiper-wrapper {
  height: auto;
}
.swiper-slide img {
  width: 100%;
  height: auto;
}

Swiperの初期化(JavaScript)

Swiperを初期化します。
初期化ではオプションパラメーターの設定をして、Swiperを起動します。

下例ではdirectionパラメーターに'horizontal'(水平方向にスライド)を設定しています。
loopパラメータをtrueにして、最後の画像の次に最初に戻るスライドショーにしています。

5行目以降(ページネーション以降)は、必要な場合に書きます。

JavaScript

const swiper = new Swiper('.swiper', {
  // Optional parameters
  direction: 'horizontal',
  // If we need pagination
  pagination: {
    el: '.swiper-pagination',
  },
  // Navigation arrows
  navigation: {
    nextEl: '.swiper-button-next',
    prevEl: '.swiper-button-prev',
  },
  // And if we need scrollbar
  scrollbar: {
    el: '.swiper-scrollbar',
  },
});

使いそうなパラメーター

パラメーターの詳細は、公式サイトにある下記ページを参考にしてください。
参考)Swiperパラメーターの詳細

パラメーターデフォルト値
autoHeight
自動高さ調整
真偽値false
breakpoints
ブレイクポイント
オブジェクト
direction
スライドの方向
'horizontal' or 'vertical''horizontal'
effect
エフェクト
'slide', 'fade', 'cube', 'coverflow',
'flip' or 'creative'
'slide'
lazyPreloadPrevNext
プリロードするスライドの数
数値0
loop
スライド最後で先頭へループ
真偽値false
rewind
スライド最後で先頭へ巻き戻る
真偽値false
slidesOffsetAfter
スライド最後に余白
数値0
slidesOffsetBefore
スライド最初に余白
数値0
slidesPerGroup
一度にスライドする数
数値1
slidesPerView
表示するスライド数
数値 or 'auto'1
spaceBetween
スライド間の余白(px)
文字列 or 数値0
speed
スライドの切替速度(ミリ秒)
数値300

Swiperのサンプルコード

コピペで使えるサンプルコードを紹介します。

上述のパラメーター以外にも、モジュール(※)を組み込みながら、使用します。
すでに紹介している、ナビゲーションボタン、ページネーション、スクロールバーのほか、使いそうなところではオートプレイ、エフェクト、サム(メインスライダーとサムネイルの連動)などがあります。
参考)Swiperモジュールの詳細

※モジュールとは、機能をSwiper本体と別に管理する単位のことです。

矢印をスライドの外に出す

上述した基本コードでは、ナビゲーションボタンやページネーションが、スライドの上に配置されていました。

スライダーの外に出すには、ナビゲーションボタンとページネーションのモジュールの表示位置を変更します。
よく見かけるスライダーのレイアウトですね。


具体的には、以下の通りです。

  • ページネーション、ナビゲーションボタンのHTML(15-19行目)をswiperクラスの外に移動
  • 大外にwrapperクラスを追加し、position: relative;を指定
  • ナビゲーションボタンのカスタムプロパティにマイナスで指定
  • ページネーションのカスタムプロパティにマイナスで指定

見た目の多くの部分が、カスタムプロパティ(CSS変数)で変更可能です。
変数名はデベロッパーツールで調べます(--swiper-*で設定されています)。
いつもどおり、クラスにスタイルを入れても構いません。

外に出すサンプルコード(コード全文)

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@9/swiper-bundle.min.css"/>
<script src="https://cdn.jsdelivr.net/npm/swiper@9/swiper-bundle.min.js"></script>

<!-- Slider main container -->
<div class="wrapper">
  <div class="swiper">
    <!-- Additional required wrapper -->
    <div class="swiper-wrapper">
      <!-- Slides -->
      <div class="swiper-slide"><img src="/slideshow_img_1.jpg"></div>
      <div class="swiper-slide"><img src="/slideshow_img_2.jpg"></div>
      <div class="swiper-slide"><img src="/slideshow_img_3.jpg"></div>
    </div>  
  </div>
  <!-- pagination -->
  <div class="swiper-pagination"></div>
  <!-- navigation buttons -->
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>
</div>

<style>
.wrapper {
  position: relative; /* ナビゲーション、ページネーションの位置決めに必要 */
  max-width: 1000px; /* サイトにあわせて任意で */
  margin: 0 auto;
}
.swiper {
  --swiper-navigation-sides-offset: -40px; /* ナビゲーションボタンの位置 */
  --swiper-pagination-bottom: -20px; /* ページネーションの位置 */
}
</style>

<script>
  const swiper = new Swiper('.swiper', {
  // Optional parameters
  direction: 'horizontal',
  loop: true, // スライドのループ
  // If we need pagination
  pagination: {
    el: '.swiper-pagination',
  },
  // Navigation arrows
  navigation: {
    nextEl: '.swiper-button-next',
    prevEl: '.swiper-button-prev',
  },
});
</script>

矢印を変更する

仕事では、SVG画像で用意することが多いので、今回はSVG画像で丸矢印に変更しました。
png画像の場合は、imgタグで画像配置すればOKです。


具体的には、以下の通りです。

  • swiper-button-prevクラスに包含するように画像を配置(18行目)
  • swiper-button-nextクラスに包含するように画像を配置(19行目)
  • CSSを調整(30-57行目)
  • デフォルトの矢印を非表示(58-63行目)
  • ページネーションのアクティブ時の色を変更(64-66行目)

矢印変更のサンプルコード(コード全文)

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@9/swiper-bundle.min.css"/>
<script src="https://cdn.jsdelivr.net/npm/swiper@9/swiper-bundle.min.js"></script>

<!-- Slider main container -->
<div class="wrapper">
  <div class="swiper">
    <!-- Additional required wrapper -->
    <div class="swiper-wrapper">
      <!-- Slides -->
      <div class="swiper-slide"><img src="/slideshow_1.jpg"></div>
      <div class="swiper-slide"><img src="/slideshow_2.jpg"></div>
      <div class="swiper-slide"><img src="/slideshow_3.jpg"></div>
    </div>  
  </div>
  <!-- pagination -->
  <div class="swiper-pagination"></div>
  <!-- navigation buttons -->
  <div class="swiper-button-prev"><svg role="img" aria-hidden="true"><use xlink:href="#arrow"></use></svg></div>
  <div class="swiper-button-next"><svg role="img" aria-hidden="true"><use xlink:href="#arrow"></use></svg></div>
</div>
<!-- 矢印ボタン -->
<svg xmlns="http://www.w3.org/2000/svg" style="display:none">
  <symbol id="arrow" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path d="M16 24.25C15.5858 24.25 15.25 24.5858 15.25 25C15.25 25.4142 15.5858 25.75 16 25.75V24.25ZM34.0303 25.5303C34.3232 25.2374 34.3232 24.7626 34.0303 24.4697L29.2574 19.6967C28.9645 19.4038 28.4896 19.4038 28.1967 19.6967C27.9038 19.9896 27.9038 20.4645 28.1967 20.7574L32.4393 25L28.1967 29.2426C27.9038 29.5355 27.9038 30.0104 28.1967 30.3033C28.4896 30.5962 28.9645 30.5962 29.2574 30.3033L34.0303 25.5303ZM16 25.75H33.5V24.25H16V25.75Z" fill="#3C646E"/>
    <circle cx="25" cy="25" r="24.5" stroke="#3C646E"/>
  </symbol>    
</svg>

<style>
.wrapper {
  position: relative; /* ナビゲーション、ページネーションの位置決めに必要 */
  max-width: 1000px; /* サイトにあわせて任意で */
  margin: 0 auto;
}
/* ナビゲーションボタンとページネーションの位置 */
.wrapper {
  --swiper-navigation-sides-offset: -25px; /* ナビゲーションボタンの位置 */
  --swiper-pagination-bottom: -20px; /* ページネーションの位置 */
}
/* 矢印ボタン */
.swiper-button-next, .swiper-button-prev {
  width: 50px; /* 矢印幅 */
  height: 50px; /* 矢印高さ */
}
.swiper-button-next svg, .swiper-button-prev svg {
  width: 50px; /* 矢印幅 */
  height: 50px; /* 矢印高さ */  
  fill: #000; /* 矢印の色 */
  stroke: #000; /* 外周円の色 */
  transition: 0.2s;
}
.swiper-button-next svg:hover, .swiper-button-prev svg:hover {
  opacity: 0.7; /* ボタンホバー時 */
}
.swiper-button-prev svg {
  transform: rotate(180deg); /* ボタンを反転(prev用) */
}
.swiper-button-prev::after, .swiper-rtl .swiper-button-next::after {
  content: ''; /* デフォルトの矢印を削除 */
}
.swiper-button-next::after, .swiper-rtl .swiper-button-prev::after {
  content: ''; /* デフォルトの矢印を削除 */
}
.wrapper {
  --swiper-pagination-color: #000;  /* ページネーション、アクティブ時のドットの色 */
}
</style>

<script>
  const swiper = new Swiper('.swiper', {
  // Optional parameters
  direction: 'horizontal',
  loop: true,
  // If we need pagination
  pagination: {
    el: '.swiper-pagination',
  },
  // Navigation arrows
  navigation: {
    nextEl: '.swiper-button-next',
    prevEl: '.swiper-button-prev',
  },
});
</script>

ページネーションをカスタマイズ

おもに、ページネーションのをカスタマイズします。
今回は、丸形状に数字を表示するようになっています。

具体的には、以下の通りです。

  • CSSで形状を大きな丸に変更(1-16行目)
  • Swiperを初期化するJavaScrip内に追加(24-31行目)

丸形状のサンプルコード(差分)

<style>
.swiper-pagination-bullet {
  --swiper-pagination-bullet-width: 20px;
  --swiper-pagination-bullet-height: 20px;
  text-align: center;
  line-height: 20px;
  font-size: 12px;
  color: #000;
  opacity: 1;
  background: rgba(0, 0, 0, 0.2);
}
.swiper-pagination-bullet-active {
  color: #fff;
  background: #007aff; /* アクティブ時の青丸 */
}
</style>

<script>
const swiper = new Swiper('.swiper', {
  // Optional parameters
  direction: 'horizontal',
  loop: true,
  // If we need pagination
  pagination: {
    el: ".swiper-pagination",
    clickable: true,
    dynamicBullets: true,
    dynamicMainBullets: 2,
    renderBullet: function (index, className) {
      return '<span class="' + className + '">' + (index + 1) + "</span>";
    },
  },
});
</script>
clickableドットをクリック可能にする(デフォルト値: false)
dynamicBulletsドットの大きさに差をつけて、アクティブを把握しやすいデザインに
(デフォルト値: false)
dynamicMainBulletsdynamicBullets: true; 時に大きなドットの数を指定(デフォルト値: 1)
renderBulletページネーションに数字を表示したり、デザインを変更したりできる
typeページネーションのタイプを選択
'bullets' , 'fraction' , 'progressbar' or 'custom'(デフォルト値: 'bullets'


アクティブに青色を塗っていますが、borderで丸枠にもできます。

アクティブに丸枠

.swiper-pagination-bullet-active {
  color: #fff;
  background: transparent;
  border: 1px solid #fff;
}


CSSをいじると、ページネーションを縦に並べられます(dynamicBulletsは使わないこと)。

ページネーションを分数に

type: fraction(分数)を選択して、レイアウトを変更します。
今回は、左隅に表示しています。

具体的には、以下の通りです。

  • フォントを入れて(1-4行目、10行目)
  • 数字を二桁表示に変更し(42-47行目)
  • レイアウト用のタグを追加して出力(48-50行目)

分数のサンプルコード(差分)

<!-- Google Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Montserrat&display=swap" rel="stylesheet"> 

<style>
/* ページネーション */
.pagenation-wrapper {
  position: relative;
  font-family: 'Montserrat', sans-serif;
  font-size: 30px;  
  letter-spacing: 2px;  
  margin: 10px;
}
.swiper-pagination-current {
  position: absolute;
  bottom: 30px;
  left: 0;
  color: #ff8a3d; /* 文字色 */
}
.divide {
  position: absolute;
  left: 177px;
  bottom: 0;  
}
.swiper-pagination-total {
  position: absolute;
  left: 40px;
  bottom: 0;
}
</style>

<script>
const swiper = new Swiper('.swiper', {
  // Optional parameters
  direction: 'horizontal',
  loop: true,
  // If we need pagination
  pagination: {
    el: ".swiper-pagination",
    type: "fraction",
    formatFractionCurrent: function (number) {
      return ('0' + number).slice(-2); // 先頭に0をつける、二桁表示
    },
    formatFractionTotal: function (number) {
      return ('0' + number).slice(-2); // 先頭に0をつける、二桁表示
    },    
    renderFraction: function (currentClass, totalClass) {
      return '<div class="pagenation-wrapper"><div class="' + currentClass + '"></div>' + '<div class="divide">/</div>' + '<div class="' + totalClass + '"></div></div>';
    },  
  },
});
</script>
formatFractionCurrent現在のスライド番号を取得できる
formatFractionTotalスライドの総数を取得できる
renderFraction〇/〇という表示形式を変更できる

プログレスバー

スライドの切り替わるタイミングを表示するようなプログレスバーではありません。

スライドの何枚目かをバーで表示します(下画像は、4/6を表示しています)。
デフォルトでは上部に配置されていますので、CSSをいじって、下部に移動し、色をオレンジに変更しました。

プログレスバー(差分)

/* プログレスバー */
.swiper-pagination-progressbar .swiper-pagination-progressbar-fill {
  background: #ff8a3d; /* プログレスバーの色 */
}
.swiper-horizontal > .swiper-pagination-progressbar, .swiper-pagination-progressbar.swiper-pagination-horizontal, .swiper-pagination-progressbar.swiper-pagination-vertical.swiper-pagination-progressbar-opposite, .swiper-vertical > .swiper-pagination-progressbar.swiper-pagination-progressbar-opposite {
  top: auto;
  bottom: 0; /* 下部に配置 */
}
</style>

<script>
const swiper = new Swiper('.swiper', {
  // Optional parameters
  direction: 'horizontal',
  loop: true,
  // If we need pagination
  pagination: {
    el: ".swiper-pagination",
    type: "progressbar",
  },
});
</script>


切り替わるタイミングを表示するタイプも、デモサイにあります。

オートプレイ

多くのスライダーで、自動スライドが必要かと思います。
Swiperを初期化するJavaScript内に追加します。

オートプレイ(差分)

const swiper = new Swiper('.swiper', {
 autoplay: {
   delay: 5000, //5000ミリ秒停止
   pauseOnMouseEnter: true,
   disableOnInteraction: false,
 },
});
delayスライドが切り替わった後の停止時間(デフォルト値: 3000)
pauseOnMouseEnterマウスカーソルが載ったときにスライドを止める(デフォルト値: false)
disableOnInteractionユーザーのスワイプ後にオートプレイを停止する(デフォルト値: true)

横並び(カルーセル)

マニュアルによると、loop: true の場合、スライドの合計数は >= slidesPerView * 2 である必要があります。
要するに3枚横並びしているときに、スライドが5枚しかないときは、ループしません。
その場合は、rewind: true で巻き戻しを必要があります(こちらは動作します)。

横並び(差分)

<script>
const swiper = new Swiper('.swiper', {
  // Optional parameters
  direction: 'horizontal',
  loop: true,
  slidesPerView: 3, // 3枚横並び
  slidesPerGroup: 3, // 3枚セットで切り替わる
  spaceBetween: 10, // 画像間の余白
  // If we need pagination
  pagination: {
    el: ".swiper-pagination",
  },
});
</script>
slidesPerGroup一度にスライドする数(デフォルト値: 1)
slidesPerView表示するスライド数で小数値も可能(デフォルト値: 1)
spaceBetweenスライド間の余白 px(デフォルト値: 0)

左右ちょい見え

カルーセルの別バージョン。左右がちょっとずつ見えているスライダーです。
パラ―メーター centeredSlides、slidesPerView(小数値を入れる) で実装できます。

左右ちょい見えSwiper


ブレイクポイントごとにパラメーターを調整すると、スライドの見せ方が変えられます。

ちょい見えサンプルコード(差分)

<style>
/* 矢印とページネーションの色 */
.swiper-button-next, .swiper-button-prev {
  --swiper-navigation-color: #eee; /* 矢印の色 */
}
.swiper-pagination-bullet-active {
  --swiper-pagination-color: #000; /* ページネーション、アクティブの色 */
}
</style>

<script>
const swiper = new Swiper('.swiper', {
  // Optional parameters
  direction: 'horizontal',
  loop: true,
  slidesPerView: 1, // 左右なし
  breakpoints: {
    // 800px以上
    800: {
      centeredSlides: true, // 中央を大きく  
      slidesPerView: 1.5, // 0.25ずつ左右に
      spaceBetween: 10,
    },
  },
  autoplay: {
   delay: 5000, //5000ミリ秒停止
   pauseOnMouseEnter: true,
  },  
  // If we need pagination
  pagination: {
    el: ".swiper-pagination",
  },
  // Navigation arrows
  navigation: {
    nextEl: '.swiper-button-next',
    prevEl: '.swiper-button-prev',
  }, 
});
</script>
パラメーター
breakpointsブレイクポイント
centeredSlidesアクティブのスライドを中央に(デフォルト値: 1)
slidesPerView表示するスライド数で小数値も可能(デフォルト値: 1)

遅延読み込み

読込直後に画面外の画像を読み込まないで、スクロールするうちに、表示直前になって読み込む設定です。

img要素に loading="lazy" をつけるだけで、ver.9以降はブラウザーの機能をそのまま使っています。
テストしましたが、動作していました。

遅延読み込み(差分)

<!-- Slider main container -->
<div class="swiper">
  <!-- Additional required wrapper -->
  <div class="swiper-wrapper">
    <!-- Slides -->
    <div class="swiper-slide"><img src="/slideshow_1.jpg" loading="lazy"></div>
    <div class="swiper-slide"><img src="/slideshow_2.jpg" loading="lazy"></div>
    <div class="swiper-slide"><img src="/slideshow_3.jpg" loading="lazy"></div>
  </div>
  <!-- If we need pagination -->
  <div class="swiper-pagination"></div>
  <!-- navigation buttons -->
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>
</div>

フェードエフェクト

エフェクトの種類には、フェード、キューブ、カバーフロー、フリップ、カード、クリエイティブがあります。
参考)Swiper公式のデモサイト

フェード以外は癖があるので、使いどころが難しいかも。

フェードエフェクト(差分)

const swiper = new Swiper('.swiper', {
  effect: 'fade',
  fadeEffect: {
    crossFade: true,
  },
});

その他

その他、メインスライダーとサムネイルの連動やズーム機能があります。
カラーミーショップで使える機能なので、別記事で紹介します。

おわりに

今回は、よく使いそうなサンプルを書きました。
一部コードを省略しているところがありますので、正常動作しないときは不足コードがないか見なおしてください。

変更したいクラスやカスタムプロパティはデベロッパーツールで確認します。

Swiper StudioというGUI(Graphical User Interface)で、画面を見ながらパラメーターなどをいじれる機能があります。コーディングが苦手な方は、こちらをメインに学習するとよいでしょう。

執筆者

えいじ@naeco.jp この記事を書いた人

メーカー系情報システム部門出身の個人事業主。
自作するのが好きですぐに試したくなる、凝り性なWebエンジニア。
カラーミーショップ、モールなどのECについて記事にしています。

ご相談・お問い合わせはこちら