Font Face
Teva Sans Latin

Drafts & Templates
PBS Templates

Primitives & components context

Primitives & components: Teva SCS

Slider Card preset

v0.0.0

This page shows examples of displaying Cards in a slider, using the Card preset.

Cards are centered and will loop if there are enough cards to fill the available space. On bigger screens the middle cards align equal to a Container with modifier --column.

The footer is very specific to this preset mode. It can contain a button and always contains the navigation controls. The footer is wrapped by a Container with modifier --column.

This is a preset mode. All other slider options are unavailable when using this preset. Only options described on this page will work. Please regard this as an element on its own.


Enable preset #

To enter the preset mode:

  • set data-attribute data-slider-card to true
  • add modifier --card to elements with class .vi-slider__slide
  • use footer markup from examples.
alt text

Heirloom chambray celiac pop-up tousled vinyl

Pinterest meh
alt text

Franzen +1 wolf pickled listicle migas diy chillwave artisan williamsburg

Waistcoat kombucha
alt text

Cold-pressed franzen ugh ethical marfa

Cray semiotics
alt text

Pop-up meggings organic tacos aesthetic hammock selfies microdosing authentic street

Pbr&b scenester
alt text

Wayfarers lumbersexual narwhal austin yuccie diy

Xoxo normcore

<!-- Container  -->
<div class="vi-container">
  <!-- Wrapped in container for this example -->
  <!-- Slider (mods: ) -->
  <div class="vi-slider" data-slider-card="true">
    <div class="vi-slider__slides">
      <div class="vi-slider__wrapper">
        <!-- Add slides here. -->
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
      </div>
    </div>
    <!-- Container (mods: --column, --) -->
    <div class="vi-container vi-container--column vi-container--">
      <div class="vi-slider__footer">
        <div class="vi-slider__trigger">
          <!-- Button type: underline  -->
          <a href="#" class="vi-btn-underline vi-btn">Knausgaard schlitz</a>
        </div>
        <div class="vi-slider__controls">
          <div class="vi-slider__navigation vi-slider__navigation--prev">
            <!-- Button type: pagination  -->
            <button type="button" class="vi-btn-pagination vi-btn-pagination--prev vi-btn-pagination--inversed vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--prev vi-btn-pagination__label--inversed vi-btn__label">Previous</span></button>
          </div>
          <div class="vi-slider__navigation vi-slider__navigation--next">
            <!-- Button type: pagination  -->
            <button type="button" class="vi-btn-pagination vi-btn-pagination--next vi-btn-pagination--inversed vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--next vi-btn-pagination__label--inversed vi-btn__label">Next</span></button>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

When the total card width does not exceed the width of the slider, it will disable.

alt text

Forage xoxo ethical flexitarian retro vegan brunch crucifix gentrify banjo

Quinoa cold-pressed
alt text

Slow-carb iphone polaroid lumbersexual literally banjo

Meditation xoxo
[visual alignment test]

<!-- Container  -->
<div class="vi-container">
  <!-- Wrapped in container for this example -->
  <!-- Slider (mods: ) -->
  <div class="vi-slider" data-slider-card="true">
    <div class="vi-slider__slides">
      <div class="vi-slider__wrapper">
        <!-- Add slides here. -->
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
      </div>
    </div>
    <!-- Container (mods: --column, --) -->
    <div class="vi-container vi-container--column vi-container--">
      <div class="vi-slider__footer">
        <div class="vi-slider__trigger">
          <!-- Button type: underline  -->
          <a href="#" class="vi-btn-underline vi-btn">Cardigan lo-fi</a>
        </div>
        <div class="vi-slider__controls">
          <div class="vi-slider__navigation vi-slider__navigation--prev">
            <!-- Button type: pagination  -->
            <button type="button" class="vi-btn-pagination vi-btn-pagination--prev vi-btn-pagination--inversed vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--prev vi-btn-pagination__label--inversed vi-btn__label">Previous</span></button>
          </div>
          <div class="vi-slider__navigation vi-slider__navigation--next">
            <!-- Button type: pagination  -->
            <button type="button" class="vi-btn-pagination vi-btn-pagination--next vi-btn-pagination--inversed vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--next vi-btn-pagination__label--inversed vi-btn__label">Next</span></button>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Autoplay #

To enable autoplay:

  • data-slider-autoplay [milliseconds] when set, starts autoplay of slides.
  • data-slider-autoplay-inactivity [milliseconds] when set, starts an inactivity timer that makes autoplay enabled if user does not interact with the slider for the given period.
  • data-slider-direction [rtl*|ltr] sets the slide-direction of the autoplay.

Note that this will only work when no alignment is applied


Aligned #

To align the cards:

  • set data-attribute data-slider-card-alignment [left|right]
  • add modifier .vi-slider--left-aligned and .vi-container--slider-left-aligned.
  • add modifier --left-aligned to element with class .vi-slider.
  • add modifier --slider-left-aligned to the Container wrapping the footer.

The slider will not loop and de cards will not be centered.

alt text

Post-ironic freegan butcher vegan synth flexitarian xoxo chillwave kinfolk brooklyn mlkshk

Bespoke post-ironic
alt text

Lumbersexual pitchfork vegan humblebrag yolo

Vinyl ethical
alt text

Pinterest butcher vice truffaut lumbersexual diy celiac knausgaard pabst post-ironic

Hoodie etsy
[visual alignment test]
alt text

Hoodie gentrify hammock freegan meggings

Farm-to-table sriracha
alt text

Paleo humblebrag sriracha park cold-pressed yolo yuccie sustainable etsy semiotics

Poutine xoxo
alt text

Cleanse listicle brunch crucifix fingerstache

Plaid yr
alt text

Lomo tilde semiotics banjo seitan thundercats hashtag yolo leggings kinfolk beard

Iphone beard
alt text

Intelligentsia authentic ethical pug marfa

Irony sartorial

<!-- Container  -->
<div class="vi-container">
  <!-- Wrapped in container for this example -->
  <!-- Slider (mods: --align-left) -->
  <div class="vi-slider vi-slider--align-left" data-slider-card-alignment="left" data-slider-card="true">
    <div class="vi-slider__slides">
      <div class="vi-slider__wrapper">
        <!-- Add slides here. -->
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
      </div>
    </div>
    <!-- Container (mods: --column, --slider-align-left) -->
    <div class="vi-container vi-container--column vi-container--slider-align-left">
      <div class="vi-slider__footer">
        <div class="vi-slider__trigger">
          <!-- Button type: underline  -->
          <a href="#" class="vi-btn-underline vi-btn">Cleanse authentic</a>
        </div>
        <div class="vi-slider__controls">
          <div class="vi-slider__navigation vi-slider__navigation--prev">
            <!-- Button type: pagination  -->
            <button type="button" class="vi-btn-pagination vi-btn-pagination--prev vi-btn-pagination--inversed vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--prev vi-btn-pagination__label--inversed vi-btn__label">Previous</span></button>
          </div>
          <div class="vi-slider__navigation vi-slider__navigation--next">
            <!-- Button type: pagination  -->
            <button type="button" class="vi-btn-pagination vi-btn-pagination--next vi-btn-pagination--inversed vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--next vi-btn-pagination__label--inversed vi-btn__label">Next</span></button>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
<!-- Container  -->
<div class="vi-container">
  <!-- Wrapped in container for this example -->
  <!-- Slider (mods: --align-right) -->
  <div class="vi-slider vi-slider--align-right" data-slider-card-alignment="right" data-slider-card="true">
    <div class="vi-slider__slides">
      <div class="vi-slider__wrapper">
        <!-- Add slides here. -->
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
      </div>
    </div>
    <!-- Container (mods: --column, --slider-align-right) -->
    <div class="vi-container vi-container--column vi-container--slider-align-right">
      <div class="vi-slider__footer">
        <div class="vi-slider__trigger">
          <!-- Button type: underline  -->
          <a href="#" class="vi-btn-underline vi-btn">Keffiyeh tofu</a>
        </div>
        <div class="vi-slider__controls">
          <div class="vi-slider__navigation vi-slider__navigation--prev">
            <!-- Button type: pagination  -->
            <button type="button" class="vi-btn-pagination vi-btn-pagination--prev vi-btn-pagination--inversed vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--prev vi-btn-pagination__label--inversed vi-btn__label">Previous</span></button>
          </div>
          <div class="vi-slider__navigation vi-slider__navigation--next">
            <!-- Button type: pagination  -->
            <button type="button" class="vi-btn-pagination vi-btn-pagination--next vi-btn-pagination--inversed vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--next vi-btn-pagination__label--inversed vi-btn__label">Next</span></button>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Centered #

To align the cards:

  • remove modifier --column from the Container wrapping the footer.

The slider will loop and de cards will fit the --column Container wrapping the whole slider.

alt text

Taxidermy beard occupy cold-pressed hoodie typewriter

Pug polaroid
alt text

Cliche lo-fi heirloom locavore mlkshk poutine mlkshk helvetica yuccie cleanse vinegar

Quinoa yuccie
alt text

Phlogiston diy xoxo squid cold-pressed

Vegan tilde
alt text

Cornhole tumblr banjo mumblecore cardigan kogi ennui skateboard mixtape vinegar

Viral sustainable
alt text

Semiotics pinterest celiac bitters ramps

Artisan migas
[visual alignment test]

<!-- Container (mods: --column) -->
<div class="vi-container vi-container--column">
  <!-- Wrapped in container for this example -->
  <!-- Slider (mods: ) -->
  <div class="vi-slider" data-slider-card="true">
    <div class="vi-slider__slides">
      <div class="vi-slider__wrapper">
        <!-- Add slides here. -->
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
      </div>
    </div>
    <!-- Container (mods: ) -->
    <div class="vi-container">
      <div class="vi-slider__footer">
        <div class="vi-slider__trigger">
          <!-- Button type: underline  -->
          <a href="#" class="vi-btn-underline vi-btn">Yuccie retro</a>
        </div>
        <div class="vi-slider__controls">
          <div class="vi-slider__navigation vi-slider__navigation--prev">
            <!-- Button type: pagination  -->
            <button type="button" class="vi-btn-pagination vi-btn-pagination--prev vi-btn-pagination--inversed vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--prev vi-btn-pagination__label--inversed vi-btn__label">Previous</span></button>
          </div>
          <div class="vi-slider__navigation vi-slider__navigation--next">
            <!-- Button type: pagination  -->
            <button type="button" class="vi-btn-pagination vi-btn-pagination--next vi-btn-pagination--inversed vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--next vi-btn-pagination__label--inversed vi-btn__label">Next</span></button>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

When cards fit container (unregarding the gap), the slider will disable.

alt text

Cleanse cliche skateboard typewriter etsy dreamcatcher

Banjo whatever
alt text

Flexitarian park marfa humblebrag fingerstache artisan etsy occupy whatever ramps everyday

Yr vegan

<!-- Container (mods: --column) -->
<div class="vi-container vi-container--column">
  <!-- Wrapped in container for this example -->
  <!-- Slider (mods: ) -->
  <div class="vi-slider" data-slider-card="true">
    <div class="vi-slider__slides">
      <div class="vi-slider__wrapper">
        <!-- Add slides here. -->
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
      </div>
    </div>
    <!-- Container (mods: ) -->
    <div class="vi-container">
      <div class="vi-slider__footer">
        <div class="vi-slider__trigger">
          <!-- Button type: underline  -->
          <a href="#" class="vi-btn-underline vi-btn">Literally kinfolk</a>
        </div>
        <div class="vi-slider__controls">
          <div class="vi-slider__navigation vi-slider__navigation--prev">
            <!-- Button type: pagination  -->
            <button type="button" class="vi-btn-pagination vi-btn-pagination--prev vi-btn-pagination--inversed vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--prev vi-btn-pagination__label--inversed vi-btn__label">Previous</span></button>
          </div>
          <div class="vi-slider__navigation vi-slider__navigation--next">
            <!-- Button type: pagination  -->
            <button type="button" class="vi-btn-pagination vi-btn-pagination--next vi-btn-pagination--inversed vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--next vi-btn-pagination__label--inversed vi-btn__label">Next</span></button>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Less than 3 items align correctly

alt text

Pitchfork fingerstache kogi keffiyeh freegan

Salvia literally
alt text

Poutine bespoke hammock banjo authentic heirloom +1 chia kickstarter ethical

Paleo kitsch

<!-- Container (mods: --column) -->
<div class="vi-container vi-container--column">
  <!-- Wrapped in container for this example -->
  <!-- Slider (mods: ) -->
  <div class="vi-slider" data-slider-card="true">
    <div class="vi-slider__slides">
      <div class="vi-slider__wrapper">
        <!-- Add slides here. -->
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
      </div>
    </div>
    <!-- Container (mods: ) -->
    <div class="vi-container">
      <div class="vi-slider__footer">
        <div class="vi-slider__trigger">
          <!-- Button type: underline  -->
          <a href="#" class="vi-btn-underline vi-btn">Knausgaard vinegar</a>
        </div>
        <div class="vi-slider__controls">
          <div class="vi-slider__navigation vi-slider__navigation--prev">
            <!-- Button type: pagination  -->
            <button type="button" class="vi-btn-pagination vi-btn-pagination--prev vi-btn-pagination--inversed vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--prev vi-btn-pagination__label--inversed vi-btn__label">Previous</span></button>
          </div>
          <div class="vi-slider__navigation vi-slider__navigation--next">
            <!-- Button type: pagination  -->
            <button type="button" class="vi-btn-pagination vi-btn-pagination--next vi-btn-pagination--inversed vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--next vi-btn-pagination__label--inversed vi-btn__label">Next</span></button>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

With data-slider-loop [true*|false] you can disable the loop mode on the card preset. Note that this will also disable centering of the cards (it can not work without loop), which can be fine when cards are centered by the container.

alt text

Intelligentsia ramps kogi forage yolo

Portland mlkshk
alt text

Hammock vinyl neutra whatever meggings intelligentsia bitters cleanse crucifix plaid typewriter

Williamsburg schlitz
alt text

Tilde whatever slow-carb butcher asymmetrical shoreditch

90's offal
alt text

Twee phlogiston pour-over flannel austin fixie pug cray lomo selfies everyday

Plaid plaid
alt text

Cold-pressed master salvia retro pinterest

Schlitz offal

<!-- Container (mods: --column) -->
<div class="vi-container vi-container--column">
  <!-- Wrapped in container for this example -->
  <!-- Slider (mods: ) -->
  <div class="vi-slider" data-slider-card="true" data-slider-loop="false">
    <div class="vi-slider__slides">
      <div class="vi-slider__wrapper">
        <!-- Add slides here. -->
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
        <div class="vi-slider__slide vi-slider__slide--card">
          <!-- Card type: story -->
          ...
        </div>
      </div>
    </div>
    <!-- Container (mods: ) -->
    <div class="vi-container">
      <div class="vi-slider__footer">
        <div class="vi-slider__trigger">
          <!-- Button type: underline  -->
          <a href="#" class="vi-btn-underline vi-btn">Taxidermy post-ironic</a>
        </div>
        <div class="vi-slider__controls">
          <div class="vi-slider__navigation vi-slider__navigation--prev">
            <!-- Button type: pagination  -->
            <button type="button" class="vi-btn-pagination vi-btn-pagination--prev vi-btn-pagination--inversed vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--prev vi-btn-pagination__label--inversed vi-btn__label">Previous</span></button>
          </div>
          <div class="vi-slider__navigation vi-slider__navigation--next">
            <!-- Button type: pagination  -->
            <button type="button" class="vi-btn-pagination vi-btn-pagination--next vi-btn-pagination--inversed vi-btn"><span class="vi-btn-pagination__label vi-btn-pagination__label--next vi-btn-pagination__label--inversed vi-btn__label">Next</span></button>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Stylesheets #

The following stylesheets are required to display this component.

The following additional stylesheets are used to display the example(s).


JavaScript #

The following javascript is required to display this component.

The following additional javascripts are used to display the example(s).


Usage documentation #

Usage documentation can be found here.


Changelog #

Changelog

Fix

  • 26 Mar 2025 - feat(slider): add data-slider-loop to card preset.
  • 26 Mar 2025 - fix(slider): correctly disable navigation when centered by container and 3 or less cards.
  • 18 Feb 2025 - fix(slider): fix accessibility messages
  • 05 Feb 2025 - fix(slider): improve centered slides calculation to work on all zoomlevels
  • 16 Jan 2025 - fix(slider): set aria-current attributes for pagination controls to improve accessibility
  • 16 Jan 2025 - fix(slider): ensure navigation controls are enabled when loop and centeredSlides are enabled
  • 11 Nov 2024 - fix(slider): incorrect margin hero footer
  • 16 Nov 2023 - Autoplay on hover stop fix
  • 15 Sep 2023 - Hide pagination when cards total size is less than container.
  • 01 Mar 2023 - Glitch in crossfade when controlled via pagination.
  • hero footer position.
  • Workaround browser pixel rounding issues.
  • Prevent text selection next text-node after rapidly clicking the disabled next button.
  • Create room for box shadow component overlap
  • A11y outline issue button-element not receiving focus outline
  • A11y: Navigation aria attributes set to the correct element.
  • Pause/Play buttons not reflecting pause state. (js only)
  • Positioning Controls Slider with video buttons.
  • A11y slide containing element with keyboard focus scrolled into view.
  • Hero preset documentation.

Changed

  • Small change to allow usages outside .vi-container on Full Width Page Layout
  • Disabled forced load of images.
  • A11y: Optimised tab-behaviour card preset.
  • A11y: Navigation buttons are buttons now.
  • Ability to detect video mode. (js only)
  • Add ‘next slide’ as argument to slide ‘change’ event.
  • Pause autoplay when playing video in slider.
  • Accessibility: Apply ‘the’ focus outline on pagination (css)
  • Use Rectangular Image –custom in basic slider examples to prevent incorrect use.
  • Added .vi-slider__slides element as root of slider. Not using this element will be frowned upon.
  • Deprecated .vi-slider__navigation-card, .vi-slider__navigation-card--prev and .vi-slider__navigation-card--next. Use .vi-slider__navigation, .vi-slider__navigation--prev and .vi-slider__navigation--next instead.

Added