Basic Structure

Splide requires 4 components — root, track, list and slide:

<section class="splide" aria-label="Basic Structure Example">
<div class="splide__track">
<ul class="splide__list">
<li class="splide__slide">Slide 01</li>
<li class="splide__slide">Slide 02</li>
<li class="splide__slide">Slide 03</li>
</ul>
</div>
</section>
HTML

Make sure to provide a concise label to the root element. Alternatively, if your carousel has a visible heading, use aria-labelledby that indicates the ID:

<section class="splide" aria-labelledby="carousel-heading">
<h2 id="carousel-heading">Basic Structure Example</h2>
<div class="splide__track">
<ul class="splide__list">
<li class="splide__slide">Slide 01</li>
<li class="splide__slide">Slide 02</li>
<li class="splide__slide">Slide 03</li>
</ul>
</div>
</section>
HTML

You can use <div> in lieu of <section>, <ul> and <li>.

W3C suggests that the label should not include the word "carousel" because aria-roledescription is set to carousel. Some screen readers announce "label" + "description", but this behaviour is not mandatory according to the spec. Actually, some other screen readers ignore the description. IMO, we can include the word "carousel". They may say "carousel" twice — but it's trivial issue and better than nothing.

Role

Landmark Role

Many assistive technologies have a means to navigate between landmarks which are important document areas — such as banner and navigation. You can provide invisible but very useful "table of contents" for users by defining a landmark. And therefore, using <section> with an accessible name makes more sense than <div> because it has an implicit region landmark role.

I guess you may be thinking "ewww section?😑" ...okay, if you use <div> instead of <section>, Splide will assign role="region" to make it a landmark, which leads the same result.

If you are familiar with roles and you know how they affect accessibility, use the most appropriate tag and role that depend on your page architecture. Otherwise, use <div> or <section>.

Group Role

If your carousel is not so significant or not directly related to your main contents, assign role="group" to the root instead.

<div class="splide" role="group" aria-label="Unimportant Content">
<div class="splide__track">...</div>
</div>
HTML

Restriction

The HTML structure of v4 becomes more flexible than old versions'. You have to keep only two things:

  • Do not insert any elements in track and list elements
  • Do not break the relation of track > list > slide — a list element must be a child of a track, and slides must be children of a list

The track element does not have to be a child of the root element, which means the following example is also valid:

<section class="splide" aria-label="Restriction Example">
<div>
<div>
<div>
<div class="splide__track">
<ul class="splide__list">
<li class="splide__slide">...</li>
</ul>
</div>
</div>
</div>
</div>
</section>
HTML

But the next example is invalid since the relation becomes track > div > list > slide:

<section class="splide" aria-label="Incorrect Structure Example">
<div class="splide__track">
<div>
<ul class="splide__list">
<li class="splide__slide">...</li>
</ul>
</div>
</div>
</section>
HTML

Be careful not to break core components by styles of wrapper elements.

Slide Container

The purpose of the container element is to set height on a part of a slide and keep slide height adaptive to the inner content. This is especially useful when you want to use cover mode and add headings or descriptions in your slides.

In the example below, the height of images is 9rem, but the height of slides is the max height of the content among all slides.

  • 06
    Nibh veri dolor in eam. At homero volumus eos, ea vix quas omnes temporibus.
  • 07
    Feugiat quaerendum ad eam, at hinc graeci rationibus pri. Ei viris labitur consectetuer mei.
  • 08
    Suas inani rationibus duo ne, sit no epicurei dissentiet reprehendunt. Ea sed primis recteque consulatu.
  • 09
    Duis constituto eam ex, sit rebum nonumes eu. Ut sea summo consul necessitatibus.
  • 01
    Lorem ipsum dolor sit amet, in duo falli epicurei. Te has saperet veritus efficiendi.
  • 02
    Suas integre probatus vel ex, veniam qualisque tincidunt ius id.
  • 03
    Alii blandit accusamus usu cu, omnis neglegentur nec ex.
  • 04
    Mei facilisi erroribus ocurreret ei. Te soluta assueverit pri, has no tempor ceteros reprehendunt.
  • 05
    Primis delenit theophrastus at sea, sed scripta vocibus adipiscing ea. Timeam denique lucilius vix te.
  • 06
    Nibh veri dolor in eam. At homero volumus eos, ea vix quas omnes temporibus.
  • 07
    Feugiat quaerendum ad eam, at hinc graeci rationibus pri. Ei viris labitur consectetuer mei.
  • 08
    Suas inani rationibus duo ne, sit no epicurei dissentiet reprehendunt. Ea sed primis recteque consulatu.
  • 09
    Duis constituto eam ex, sit rebum nonumes eu. Ut sea summo consul necessitatibus.
  • 01
    Lorem ipsum dolor sit amet, in duo falli epicurei. Te has saperet veritus efficiendi.
  • 02
    Suas integre probatus vel ex, veniam qualisque tincidunt ius id.
  • 03
    Alii blandit accusamus usu cu, omnis neglegentur nec ex.
  • 04
    Mei facilisi erroribus ocurreret ei. Te soluta assueverit pri, has no tempor ceteros reprehendunt.

To realize that, wrap images by a <div> element with the .splide__slide__container class. Make sure that it must be a direct child of a splide__slide element.

<section class="splide" aria-label="Slide Container Example">
<div class="splide__track">
<ul class="splide__list">
<li class="splide__slide">
<div class="splide__slide__container">
<img src="...">
</div>
Lorem Ipsum Dolor Sit Amet
</li>
<li class="splide__slide">
<div class="splide__slide__container">
<img src="...">
</div>
Lorem Ipsum Dolor Sit Amet
</li>
</ul>
</div>
</section>
HTML

Splide applies height, heightRatio or fixedHeight to containers instead of slides.