About Version 4

バージョン4について

Splide v4

Splideは現在、jsDelivr(CDN)において、月間3億ヒット以上するライブラリにまで成長しました✨ この数値はカルーセルライブラリとして有名なSwiperの3倍ですので、なかなか善戦しているのではないかと思います(もちろん、ライブラリの配信方法は様々ですので、及ばないところはまだまだあります)。Splideを選んでいただいた方々、そしてスポンサーの皆様、ありがとうございます!

今回のアップデートは、前回のようにすべて書き直すという大がかりなものではありませんが、アクセシビリティを最新の要件に合わせ、より堅牢なものへと改善するための更新です。いくつかの追加機能を合わせ、以下のような修正をしました。

  • W3C Carousel Design Patternに準拠しながら、アクセシビリティ周りを改修
  • スクリーンリーダのためのライブリージョンを標準搭載
  • prefers-reduced-motionを検知し、重要でないトランジションを無効化する処理を追加
  • 自動再生の再生・停止ボタンを、トグル形式に変更
  • ブレークポイントを、CSSと同じふるまいになるように修正
  • フリードラッグにおいて、近いスライドにスナップできるオプションを追加
  • 方向をブレークポイントで切り替えられるようdirectionオプションをレスポンシブ化
  • 慣性スクロールを引き起こすマウスホイールのふるまいを制御できるようにオプションを追加
  • どのブラウザでも:focus-visibleを実現できるようにし、テーマにスタイルを追加
  • その他バグ修正

残念ながら、コードサイズは27Kb→29Kbと、2Kbほど増えました。

破壊的変更

以下の破壊的変更が既存のスライダーに影響する場合は、v3からv4への移行セクションを参照し、修正してください。

  • keyboardwaitForTransitionならびにslideFocusの初期値を変更
  • 自動再生を制御するための、独立した再生・停止ボタンの機能を削除。代わりに、トグル形式を採用(再生・停止を一つのボタンで管理)
  • splide__slider機能を削除し、arrows: 'slider'およびpagination: 'slider'を廃止
  • コンポーネントメソッドの一部を修正

また、新しく追加された機能に対応するため、以下の2点を更新してください(必須ではありません)。

なお、インテグレーション用パッケージを使用している場合は、それぞれの手引きを参照してください。

新しい機能について

アクセシビリティの強化

アクセシビリティをより強固で信頼できるものとするため、W3CのCarousel Design Patternに準拠するよう、ロールやARIA属性などを更新しました。また、スクリーンリーダを使用しているユーザのために、ライブリージョンを標準搭載しました。

あまり耳になじみのない言葉かもしれませんが、ライブリージョンを導入すると、動的に更新される箇所をスクリーンリーダなどの支援技術に伝えることができます。たとえば、著名なスクリーンリーダであるNVDAは、以下のようにスライドを読み上げてくれるようになります。

加えて、prefers-reduced-motion: reducedを検知した場合、スライダーのトランジションエフェクトを無効にする処理を追加しました。これは、例えばアニメーション酔いを起こしやすいユーザや、前庭運動障害を持つユーザなどが、不要な視覚効果をなるべく抑えることを要求した際に自動で有効になります(WCAG 2.3.3)。

もしアクセシビリティの改善について詳しく知りたい場合は、こちらの長いドキュメントを参照してください。

ブレークポイント

古いバージョンでは、ブレークポイントにヒットするたびに、そのポイントに割り当てられたオプションで現在のオプションを更新していました。この場合、設定の仕方によっては、ウィンドウをリサイズした場合とページをロードした場合で、異なる結果になる可能性がありました。

例えば、次のようなオプションを考えてみます。

{
perPage : 3,
gap : '1rem',
breakpoints: {
1200: { perPage: 2, gap: '1rem' },
640 : { gap: 0 },
},
}
JavaScript

1200px以上のデバイスでこのページを開いたとき、スライダーは3枚のスライドを表示します。そのままウィンドウサイズを640pxまで狭めると、1200: { perPage: 2 }を通過しますのでスライドは2枚に減ります。ところが、初めから640px以下の状態でページを開くと、スライドは2枚ではなく3枚表示されます。

意図通りの正しい結果を得るには次のように、どのポイントにも更新したいオプションを設定しておく必要がありました。

{
perPage : 3,
gap : '1rem',
breakpoints: {
1200: { perPage: 2, gap: '1rem' },
640 : { perPage: 2, gap: 0 },
},
}
JavaScript

バージョン4では下記のような理由により、CSSのメディアクエリと同じふるまいをするよう修正しました。

  • CSSとの混同を防げる
  • ウィンドウサイズ変更とページロードで、必ず同じ結果になる
  • どのオプションが使用されるか、直観的にわかりやすい

この変更により、現在のウィンドウサイズに該当するすべてのブレークポイントのオプションが、順次ベースオプションにマージされます。たとえば、

{
arrows : true,
perPage: 3,
breakpoints: {
1200: { arrows: false },
800 : { perPage: 2 },
640 : {},
},
}
JavaScript

のようなオプションを640px以下のデバイスで開いた場合、1200および800も条件を満たすため、スライドの枚数は2枚になり、矢印は無効化されます。

さらに、条件を満たさなくなったポイントのオプションは、ベースオプションで指定しない限り初期値にリセットされます。たとえば、ある特定のポイントでスライドの幅を指定したとします。

{
breakpoints: {
1200: { fixedWidth: 200 },
},
}
JavaScript

ウィンドウ幅が1200px以下のとき、スライドは200pxで表示されますが、幅を大きくしていき1200pxを超えると、スライドの幅は初期値にリセットされundefinedの状態に戻ります。

古いバージョンのブレークポイントは新しいものよりも厳密な設定を要求していたため、今回の変更によって既存のスライダーが壊れることはないと思いますが、アップグレードの際は念のため動作確認を行ってください。

v3からv4への移行

オプション

いくつかのオプションは、初期値が変更されています。状況にあわせ、適宜更新してください。


keyboard

初期値をtrueからfalseに変更しました。また、'focused'の際、tabindexをルート要素に追加する機能は廃止しました。

true

スライダー内の要素がフォーカスを持っている場合にのみショートカットを有効にする

false

ショートカットを無効にする

'global'

windowのkeydownを監視することで、常にショートカットを有効にする(非推奨)

'focused'

trueと同様

詳しくはアクセシビリティに記載があります。


waitForTransition

初期値をtrueからfalseに変更しました。2つの同期したスライダーを作成した場合、このオプションが同期を妨げるという不親切さへの対処です。


slideFocus

もとはtrueでしたが、新しいバージョンでは以下のように初期値が決定されます。

  • 通常はfalse
  • isNavitationが有効な場合true

ほかのアクセシビリティ関連の改善の結果、積極的にこのオプションを有効にする必要は「おそらく」ないと思います(現段階では、まだ確信を持てていません)。一方、isNavigationが有効の場合は、このオプションは有効である必要があります。これは、「クリックできる要素は、フォーカス可能なインタラクティブ要素でなければならない」という(かなり悩ましい)指針が存在するためです。


arrows

値に'slider'は指定できなくなりました。trueに変更したうえで、このガイドに従って修正してください。


pagination

値に'slider'は指定できなくなりました。trueに変更したうえで、このガイドに従って修正してください。


i18n

新しく、carouselslideおよびslideLabelが追加されました。このページに詳細が記載されています。


再生・停止ボタン

利用者からのフィードバックにより、分離された再生・停止ボタンよりも、単一のトグルボタンのほうが需要が高いことがわかりました。今回のバージョンから分離式は廃止されましたので、次のようにしてトグルボタンに置き換えてください。

<div class="splide">
...
<div class="splide__autoplay">
<button class="splide__play">Play</button>
<button class="splide__pause">Pause</button>
</div>
<button class="splide__toggle" type="button">
<span class="splide__toggle__play">Play</span>
<span class="splide__toggle__pause">Pause</span>
</button>
</div>
HTML

以下のようにすれば、引き続き個別のボタンを使用できます。

var splide = new Splide( '.splide', { autoplay: true } ).mount();
var Autoplay = splide.Components.Autoplay;
var play = splide.root.querySelector( '.splide__play' );
var pause = splide.root.querySelector( '.splide__pause' );
if ( play ) {
play.addEventListener( 'click', function () {
Autoplay.play();
} );
}
if ( pause ) {
pause.addEventListener( 'click', function () {
Autoplay.pause();
} );
}
JavaScript

スライダー要素

スライダー要素(<div class="splide__slider">)は、トラックをrelativeな要素で囲む目的で導入されていました。新しいバージョンでは、HTMLの構成に対する制約を緩めたため、この要素の必要性はなくなりました。同様の結果を得るためには、次のようにします。

  1. arrowspaginationオプションの値を'slider'からtrueに変更します
    {
    arrows: 'slider',
    arrows: true, // または削除
    pagination: 'slider',
    pagination: true, // または削除
    }
    JavaScript
  2. スライダー要素を、position: relativeを持った任意の<div>で置き換えます
    <div class="splide">
    <div style="position: relative">
    <div class="splide__track">
    <div class="splide__list">...</div>
    </div>
    </div>
    </div>
    HTML

もしくは.splide__sliderを独自で定義すれば、これまでのマークアップをそのまま使用できます。

.splide__slider {
posiiton: relative;
}
CSS

コンポーネント

Move#isBusy()

Controller#isBusy()に移動しました。


Controller#scroll()

引数が変わりました。詳しくはControllerを参照してください。


Scroll#scroll()

引数が変わりました。詳しくはScrollを参照してください。