Swiperでページネーションの左右に「前へ / 次へ」ボタンを配置する方法

【Swiper】スライダーページネーションの左右にボタンを配置する方法 CSS
スポンサーリンク

Swiperを使ってスライダーを作る際に、ページネーション(dots)の左右に「前へ / 次へ」ボタンが並んでいるデザインを実装するケースがたまにあります。

例えば、以下のような画像のものです。

Swiperのドットの左右に、「前へ/次へ」ボタンを配置したデザイン

ただ、Swiperのオプションを探しても、このレイアウトをそのまま実現する設定は見つかりません。

そして、意外にもこれを実現する方法を解説しているサイトが無い…!

でも安心してください!

実はこのUIは、特別な設定無しで実装できます。SwiperのHTML構造を少し理解して、CSSを少し調整するだけです。

この記事では、Swiperについて次のことを解説します。

  • ページネーションの左右に「前へ / 次へ」ボタンを配置する方法
  • SwiperのデフォルトUIをカスタマイズする方法

CodePenのデモも用意しているので、動きを確認しながら試してみてください。

本記事の執筆者:マサトラ

フリーランス歴4年のWebエンジニア。現在は20社以上のWeb制作会社社様と提携し、WordPress構築やLP制作を中心に月3~5件のペースでサイト制作を手がけています。
このブログでは、実務で得た知識やノウハウ、制作現場での気づきを、フリーランスとして活動中の方はもちろん、これからWeb制作を仕事にしたいと考えている方にも役立つよう発信しています。

スポンサーリンク

Swiperのオプションでは実装できない

Swiperには paginationnavigation の機能があります。

Swiperの公式ドキュメントを見ると、

  • pagination はページネーション用の要素
  • navigation は前へ / 次へボタン用の要素

として、別々に扱われています。

つまりSwiperは、

  • pagination を表示する
  • navigation を表示する

ところまでは用意してくれますが、

  • その2つをどう並べるか
  • dotsの左右に配置するか
  • 見た目をどう整えるか

までは残念ながら面倒を見てくれません。

なので、希望のデザインを実現させるには、HTMLとCSSで調整する必要があります。

私も最初はSwiperの設定項目を探したり、参考サイトは無いかとググりましたが、答えは見つからず…。最終的に自力で「HTMLとCSSを調整する」という結論で実現できたので、ぜひこの記事を参考にしてください。

navigationとpaginationは別機能

Swiperの基本レイアウトでは、swiper-paginationswiper-button-prev / swiper-button-next は別要素として配置されます。

そのため、何も調整しないままだと、Swiper側のデフォルトスタイルでそれぞれが配置されます。

今回やりたいのは、

  • swiper-button-prev (「前へ」ボタン)
  • swiper-pagination (ドット)
  • swiper-button-next (「次へ」ボタン)

を1列に並べて、

< ● ● ● >

のような見た目に整える、つまり要素の並び方をこちらで調整することです。

次は、実際にそのためのHTML構造を見ていきます。

解決方法:HTMLとCSSをカスタマイズする

まずはSwiperの基本的なHTML構造を確認してから、矢印ボタンとページネーションを横並びにしやすい形へ整えていきます。

Swiperの基本HTML構造

まずはSwiperの基本的にはHTML構造からみていきましょう。

<!-- 通常のSwiperのHTML構造 -->
<div class="sample-slider swiper">

  <div class="swiper-wrapper">

    <div class="swiper-slide">
      <img src="https://images.unsplash.com/photo-1567225591450-06036b3392a6?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2Nzc3MjU1NTQ&ixlib=rb-4.0.3&q=80"
      />
    </div>

    <div class="swiper-slide">
      <img src="https://images.unsplash.com/photo-1653210818916-b1d7cc5c60e6?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2Nzc3MjU1NTQ&ixlib=rb-4.0.3&q=80"
      />
    </div>

    <div class="swiper-slide">
      <img src="https://images.unsplash.com/photo-1610555770410-5d746dd977c1?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2Nzc3MjkxMjk&ixlib=rb-4.0.3&q=80"
      />
    </div>

  </div>

  <div class="swiper-pagination"></div>
  <button type="button" class="swiper-button-prev" aria-label="前のスライドへ">〈</button>
  <button type="button" class="swiper-button-next" aria-label="次のスライドへ">〉</button>

</div>
const mySwiper = new Swiper(".sample-slider", {
  loop: true,
  speed: 700,
  slidesPerView: 'auto',
  centeredSlides: true,

  // ページネーション
  pagination: {
    el: ".swiper-pagination",
    clickable: true,
  },
  // 前後の矢印
  navigation: {
    nextEl: ".swiper-button-next",
    prevEl: ".swiper-button-prev",
  },
});

Swiperの基本レイアウトはとてもシンプルです。

最低限必要になるのは、次の3つの要素です。

  • swiper
  • swiper-wrapper
  • swiper-slide

さらに、ページネーションを表示する場合は swiper-pagination、前へ / 次へボタンを表示する場合は swiper-button-prevswiper-button-next を追加します。

つまり今回のUIでも、特別なHTMLを新しく作るというより、Swiperが使う要素をそのまま利用しながら配置だけを調整していく形になります。

次のセクションでは、swiper-button-prevswiper-paginationswiper-button-next を横並びにしやすいHTML構造にしていきます。

矢印ボタンとpaginationを配置する

まずは、矢印ボタンとページネーションを同じ場所にまとめて配置します。

ポイントは、次の3つの要素を1つのラッパーに入れることです。

  • swiper-button-prev
  • swiper-pagination
  • swiper-button-next

HTMLは次のようになります。

<div class="swiper">

  <div class="swiper-wrapper">

    <div class="swiper-slide">
      <img src="dog1.jpg" alt="">
    </div>

    <div class="swiper-slide">
      <img src="cat1.jpg" alt="">
    </div>

    <div class="swiper-slide">
      <img src="dog2.jpg" alt="">
    </div>

  </div>

  <div class="swiper-controls">
    <button type="button" class="swiper-button-prev" aria-label="前のスライドへ">〈</button>
    <div class="swiper-pagination"></div>
    <button type="button" class="swiper-button-next" aria-label="次のスライドへ">〉</button>
  </div>

</div>

ここでは swiper-controls というラッパーを作り、

  • prev
  • pagination
  • next

をまとめています。

この形にしておくと、あとでCSSの flex を使って

< ● ● ● >

というレイアウトを作りやすくなります。

スポンサーリンク

CSSで「< ● ● ● >」のレイアウトを作る

HTMLを並べただけでは、まだ

< ● ● ● >

のような見た目にはなりません。

というのも、SwiperのデフォルトCSSでは、ページネーションやナビゲーションにあらかじめスタイルが入っているからです。

そのため、今回のUIを作るときは

  • swiper-pagination の幅
  • swiper-button-prev / swiper-button-next の配置方法
  • 3つの要素の並べ方

このあたりをこちらで上書きしていく必要があります。

特に引っかかりやすいのが、swiper-pagination の横幅と、矢印ボタンの position です。

私も最初はHTMLの順番を変えればいけそうに思ったのですが、実際にはCSSのデフォルト指定が効いていて、そのままではきれいに並びませんでした。

まずは、ページネーションの幅から調整していきます。

paginationのwidth: 100%問題

まず確認したいのが swiper-pagination です。

SwiperのデフォルトCSSでは、ページネーションが横幅いっぱいに広がる前提のスタイルになっています。

この状態のままだと、dotsを中央に置きつつ、その左右にボタンをきれいに並べるのが難しくなります。

そこで、まずは swiper-pagination の幅を自動サイズにします。

.swiper-pagination {
  width: auto;
}

これで、ページネーションが必要な分だけの幅を持つようになります。

dotsの横にボタンを並べたい場合は、この調整がかなり重要です。

flexで横並びレイアウトにする

.swiper-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
}

これで

  • swiper-button-prev
  • swiper-pagination
  • swiper-button-next

を1列に並べることができます。

ただし、これだけではまだ崩れることがあります。

理由は、swiper-button-prevswiper-button-next に、Swiper側のデフォルトで position: absolute が入っているためです。

absolute のままだと、flex の並びに素直に乗ってくれません。

そこで、矢印ボタンの配置方法も上書きします。

.swiper-button-prev,
.swiper-button-next {
  position: static;
  margin-top: 0;
}

position: static に戻すことで、矢印ボタンが通常の要素として並ぶようになります。

ここまでできると、prevpaginationnext

< ● ● ● >

という形にかなり近い状態まで整えられます。

Swiperのデフォルト矢印を消す

swiper-button-prevswiper-button-next には、最初から矢印アイコンが表示されます。

この矢印は要素の中に文字が入っているわけではなく、::after の疑似要素で表示されています。

そのため、ボタンの見た目を独自に作りたい場合は、まずこのデフォルト矢印を消しておくと調整しやすくなります。

.swiper-button-prev::after,
.swiper-button-next::after {
  display: none;
}

これで、デフォルトの矢印アイコンは非表示になります。

あとは、ボタン自体に背景色や文字をつければ、好みのデザインにできます。

たとえば、シンプルに を表示したいなら、HTMLを少しだけ調整しておく方法が分かりやすいです。

<div class="swiper-controls">
  <button type="button" class="swiper-button-prev" aria-label="前のスライドへ">〈</button>
  <div class="swiper-pagination"></div>
  <button type="button" class="swiper-button-next" aria-label="次のスライドへ">〉</button>
</div>

このようにしておくと、CSS側でサイズや余白を調整するだけで、かなり扱いやすくなります。

もちろん、文字の代わりにSVGアイコンを入れても問題ありません。案件によっては、デザインカンプに合わせてここを差し替えることも多いと思います。

.swiper-button-prev,
.swiper-button-next {
  position: static;
  margin-top: 0;
  width: 40px;
  height: 40px;
  border: 1px solid #333;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

ここまでで、

  • swiper-pagination の幅を調整する
  • swiper-button-prevswiper-button-nextposition: static に戻す
  • デフォルト矢印を消して独自デザインにする

という流れができました。

次は、ここまでの内容をまとめた完成コードを見ていきます。

完成コード

ここまでの内容を、まとめて実装すると次のようになります。

まずはHTMLです。

<div class="swiper sample-swiper">

  <div class="swiper-wrapper">

    <div class="swiper-slide">
      <img src="dog1.jpg" alt="犬の画像1">
    </div>

    <div class="swiper-slide">
      <img src="cat1.jpg" alt="猫の画像1">
    </div>

    <div class="swiper-slide">
      <img src="dog2.jpg" alt="犬の画像2">
    </div>

  </div>

  <div class="swiper-controls">
    <button type="button" class="swiper-button-prev" aria-label="前のスライドへ">〈</button>
    <div class="swiper-pagination"></div>
    <button type="button" class="swiper-button-next" aria-label="次のスライドへ">〉</button>
  </div>

</div>

次にCSSです。

.sample-swiper {
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
}

.sample-swiper .swiper-slide img {
  display: block;
  width: 100%;
  height: auto;
}

.sample-swiper .swiper-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin-top: 16px;
}

.sample-swiper .swiper-pagination {
  position: static;
  width: auto;
}

.sample-swiper .swiper-button-prev,
.sample-swiper .swiper-button-next {
  position: static;
  margin-top: 0;
  width: 40px;
  height: 40px;
  border: 1px solid #333;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: #333;
}

.sample-swiper .swiper-button-prev::after,
.sample-swiper .swiper-button-next::after {
  display: none;
}

最後にJavaScriptです。

const sliderElement = document.querySelector('.sample-swiper');

const swiper = new Swiper(sliderElement, {
  loop: true,
  pagination: {
    el: sliderElement.querySelector('.swiper-pagination'),
    clickable: true
  },
  navigation: {
    prevEl: sliderElement.querySelector('.swiper-button-prev'),
    nextEl: sliderElement.querySelector('.swiper-button-next')
  }
});

今回のポイントを改めて整理すると、次の3つです。

  • swiper-paginationwidthauto にする
  • swiper-button-prevswiper-button-nextpositionstatic にする
  • デフォルトの矢印を ::after で消して、独自の見た目にする

Swiperには、ページネーションの左右に矢印を配置する専用オプションはありません。

そのため、paginationnavigation を有効にしたうえで、HTMLとCSSをこちらで調整していくのが基本になります。

私も最初はSwiperの設定項目ばかり探していましたが、実際には「どのオプションを使うか」よりも、「出力された要素をどう並べるか」で考えた方が早く解決できました。

CodePenデモ

See the Pen Swiper.jsのpagination-bulletsの左右にprev/nextボタンを配置 by Sugar (@ms_da_13) on CodePen.

まとめ

今回のような

< ● ● ● >

のUIは、LPやコーポレートサイトのスライダーで時々見かけます。

ただ、Swiperのオプションを探しても、このレイアウトをそのまま作る設定はありません。

そのため最初は「Swiperではできないのでは?」と思ってしまうかもしれませんが、実際には

  • swiper-button-prev
  • swiper-pagination
  • swiper-button-next

この3つの要素をどう並べるか、というレイアウトの問題です。

私も最初にこのUIを作ったときは、Swiperの設定をかなり探しました。しかしあとから振り返ると、Swiperの機能というより「出力されたHTMLをどう扱うか」という話でした。

実務でも、ライブラリを使うときは

  • オプションで解決できる問題なのか
  • HTML / CSSで調整する問題なのか

を切り分けて考えると、解決が早くなることが多いです。

特にSwiperはデフォルトのスタイルがしっかり用意されているので、少しカスタマイズするだけで、今回のようなUIも無理なく実装できます。

もしスライダーのデザインを自由に調整したい場合は、まず swiper-paginationswiper-button-prev などの要素がどのように出力されているかを確認してみると、カスタマイズのヒントが見えてくると思います。

スポンサーリンク