【2024年版】カルーセルライブラリEmblaCarouselの紹介と他ライブラリとの比較

はじめに

この記事の概要

こんにちは、株式会社TOKOSのスギタです!
今回はJavaScriptカルーセルライブラリのEmblaCarouselの紹介と他のカルーセルライブラリとの比較を行って行きます。
今回はReactでの使用を想定しています。
筆者としてはカルーセルライブラリで今一番推しています。shadcn/uiやMantineUIなどモダンなUIライブラリにも採用されていることから今一番勢いを感じております。

対象読者

  • WEB制作/開発を行っている方

EmblaCarouselの概要(公式ドキュメント翻訳)

Embla Carousel は、ライブラリに依存しない、依存関係のない軽量のカルーセル ライブラリです。カルーセルの構築に関する最も困難な技術的課題を解決することを目的としており、残りはその高度な拡張性を利用するユーザー次第です。
柔軟性と拡張性を念頭に置いて設計されたAPI、必要に応じて機能を追加するプラグインシステム。
また、最新のすべてのブラウザで動作します。

各ライブラリの比較(2024年3月段階)

今回はライブラリの選定する際重要視する項目ごとで比較を行っていきます。比較項目は下記になります。

  • Weeklyダウンロード数
  • 最終更新日
  • Star数
  • バンドルサイズ

また今回比較用のライブラリは下記になります。
比較用としての選定条件としてオープンソース、TypeScriptサポートを条件としています。

  • Swiper
  • React Slick
  • React Responsive Carousel

Weeklyダウンロード数

EmblaCarouselSwiperReact SlickReact Responsive Carousel
359,6582,157,5881,087,293394,142

圧倒的にSwiperが一位なのは納得ですが、React SwiperがV10から非推奨になったりとしていて個人的にはVanillaJSで使う分には良いと思うのですがReact環境では少し怖いかなという印象があります。また以前ReactSwiperを使ったことがあったのですが型の参照エラーで全く使いものにならなかった記憶があります。

最終更新日

EmblaCarouselSwiperReact SlickReact Responsive Carousel
3週間前3週間前1ヶ月前2年前

この最終更新日を気にする方は多いのではないでしょうか。ReactResponsiveCarouselは最終更新日が2年前となっており、選定するにはかなり気になるところではないでしょうか。

Star数

EmblaCarouselSwiperReact SlickReact Responsive Carousel
4.7k38.3k11k2.6k

ここでも流石のSwiperです。Weeklyダウンロード数での比率的にはReact SlickよりEmblaCarouselのが高いです。

バンドルサイズ(MINIFIED + GZIPPED)

EmblaCarouselSwiperReact SlickReact Responsive Carousel
7.2kB19.4kB15.6kB9kB

上記3つの項目はどちらかというと開発者側への選定条件になるのですが、バンドルサイズはUXやSEOに関わってくる為筆者は一番重要視しています。
EmblaCarouselがReact Slickの2分の1、Swiperの約2.5分の1のバンドルサイズになっています。
この数字だけでも選定理由になるのではないでしょうか。

その他EmblaCarouselの良いところ

公式ドキュメントが読みやすい
かなり重要なことなのですが、公式ドキュメントがかなり整備されていてとても読みやすいです。またドキュメント内にジェネレータがあるため条件入力するとコード例を生成してくれます。

様々なJSライブラリにも対応
React以外にもVue,Svelte,Solidにも対応していて、それぞれのJSライブラリに対して初期セットアップ方法、API,PlugInの使用例が記載してあります。

開発環境

  • embla-carousel: 8.0.0,
  • embla-carousel-react: 8.0.0,
  • react: 18.2.0,

ライブラリの使用方法

EmblaCarouselの使用法の説明に入ります。
最低限のライブラリのお作法が5つあるため説明します。

Slide Container(親要素のCSSの指定方法)

まずは親要素(コンテナ要素)に対してFlexBoxとCSSGridを使用してレイアウトのセットアップを行います。

今回はFlexBoxで行います。

<div class="embla">
  <div class="embla__container">
    <div class="embla__slide">Slide 1</div>
    <div class="embla__slide">Slide 2</div>
    <div class="embla__slide">Slide 3</div>
  </div>
</div>

水平カルーセルの場合

.embla__container {
  display: flex;
}

垂直カルーセルの場合
垂直カルーセルの場合は高さの指定が必要になるので注意してください

.embla__container {
  display: flex;
  flex-direction: column;
  height: 200px;
}

Gridレイアウト使用例

.embla__container {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 80%;
}

Gridレイアウトでの垂直カルーセルの場合
FlexBox同様に高さの指定が必要になります。

.embla__container {
  display: grid;
  grid-auto-flow: row;
  grid-auto-rows: 80%; 
  height: 200px;
}

Slide Sizes(スライドさせる対象のサイズ指定)

ここではスライドさせる対象に対してのサイズ指定の方法を説明します。

<div class="embla">
  <div class="embla__container">
    <div class="embla__slide">Slide 1</div>
    <div class="embla__slide">Slide 2</div>
    <div class="embla__slide">Slide 3</div>
  </div>
</div>

Flexプロパティを使い指定します

.embla__slide {
  flex: 0 0 50%; //Viewポートの50%
  min-width: 0;
}

PX等で指定することも可能です。

.embla__slide {
  flex: 0 0 200px; 
  min-width: 0;
}

またスライドごとに指定することも可能です。

.embla__slide:nth-child(1) {
  flex: 0 0 30%; 
  min-width: 0;
}
.embla__slide:nth-child(2) {
  flex: 0 0 60%; 
  min-width: 0;
}

Slide Gaps(スライド間のGap)

ここではスライド間のGapの指定方法を説明します。

<div class="embla">
  <div class="embla__container">
    <div class="embla__slide">Slide 1</div>
    <div class="embla__slide">Slide 2</div>
    <div class="embla__slide">Slide 3</div>
  </div>
</div>

片方向への指定

.embla__slide {
  margin-right: 20px;
}

両方向への指定

.embla__slide {
  margin-right: 20px;
  margin-left: 10px;
}

Gridレイアウトの場合

.embla__container {
  grid-column-gap: 20px;
}

スライドごとへの指定

.embla__slide:nth-child(1) {
  margin-right: 10px;
}
.embla__slide:nth-child(2) {
  margin-right: 20px;
  margin-left: 10px;
}

Breakpoints(ブレークポイントの指定)

ここではブレークポイントの指定をしレスポンシブ対応します。

<div class="embla">
  <div class="embla__container">
    <div class="embla__slide">Slide 1</div>
    <div class="embla__slide">Slide 2</div>
    <div class="embla__slide">Slide 3</div>
  </div>
</div>

スライドサイズの変更方法

.embla__slide {
  flex: 0 0 100%; 
}
@media (min-width: 768px) {
  .embla__slide {
    flex: 0 0 50%; 
  }
}

Gapサイズの変更方法

.embla__slide {
  margin-right: 10px; 
}
@media (min-width: 768px) {
  .embla__slide {
    margin-right: 20px; 
  }
}

またOptionの変更も可能です。
Activeオプション変更の例

const options = {
  active: true,
  breakpoints: {
    '(min-width: 768px)': { active: false }
  }
}

Loopオプション変更の例
複数のViewブレークポイント指定の例

const options = {
  loop: false,
  breakpoints: {
    '(min-width: 768px)': { loop: true },
    '(min-width: 420px)': { loop: false } 
  }
}

複数のオプションも変更可能です。

const options = {
  loop: false, 
  breakpoints: {
    '(min-width: 420px)': { align: 'start' }, 
    '(min-width: 768px)': { loop: true } 
  }
}

Previous & Next Buttons(戻る、次へボタン)

今回はReactでの例を説明します。

import React, { useCallback } from 'react'
import useEmblaCarousel from 'embla-carousel-react'

export const EmblaCarousel = () => {
  const [emblaRef, emblaApi] = useEmblaCarousel()

  const scrollPrev = useCallback(() => {
    if (emblaApi) emblaApi.scrollPrev()
  }, [emblaApi])

  const scrollNext = useCallback(() => {
    if (emblaApi) emblaApi.scrollNext()
  }, [emblaApi])

  return (
    <div className="embla">
      <div className="embla__viewport" ref={emblaRef}> 
        <div className="embla__container">
          <div className="embla__slide">Slide 1</div>
          <div className="embla__slide">Slide 2</div>
          <div className="embla__slide">Slide 3</div>
        </div>
      </div>
      <button className="embla__prev" onClick={scrollPrev}> //戻るボタン
        Prev
      </button>
      <button className="embla__next" onClick={scrollNext}> //次へボタン
        Next
      </button>
    </div>
  )
}

以上で基本的なEmblaCarouselの使い方になります。

さいごに

以上でEmblaCarouselの紹介と基本的な使い方の説明を終わります。
他ライブラリより覚えることが少なく、CSSベースでサイズ変更等行えるので直感的に記述することができるのではないでしょうか。
次回はReact環境でAPIやOptionを使ってカスタムしていきたいとおもいますので少々お待ちいただけたらと思います!