Font Face
Teva Sans Latin

Drafts & Templates
PBS Templates

Primitives & components context

Primitives & components: Teva Product

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

+1 fingerstache biodiesel cardigan ennui

Meditation cliche
alt text

Cleanse gentrify narwhal vegan microdosing vice hella waistcoat goth umami

Church-key brunch
alt text

Stumptown health offal poutine aesthetic

Pug pop-up
alt text

Irony fixie echo sustainable flannel biodiesel offal tattooed cliche goth

Poutine squid
alt text

Cray biodiesel offal brooklyn echo asymmetrical

Ennui health

<!-- 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">Celiac drinking</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

Try-hard vice slow-carb pitchfork goth lumbersexual

Vice vinegar
alt text

Viral godard ramps locavore sriracha ugh drinking kogi cornhole squid

Vice kombucha
alt text

Venmo pour-over migas ramps pickled skateboard

Butcher master
[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">Cray lomo</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

Offal salvia hammock marfa celiac swag meh migas tattooed farm-to-table seitan

Pop-up meh
alt text

Scenester sartorial roof seitan migas umami beard mlkshk distillery marfa

Gastropub mumblecore
[visual alignment test]
alt text

Wayfarers gentrify loko chambray swag yolo

Offal synth
alt text

Health kombucha tattooed wolf irony goth lomo fixie ugh gastropub

Yuccie mumblecore
alt text

Occupy carry cray wayfarers asymmetrical irony umami authentic kinfolk seitan

Locavore sriracha

<!-- 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">Cronut keytar</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">Readymade portland</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

Cornhole umami twee truffaut butcher pug

Lomo chillwave
alt text

Banjo bespoke irony +1 retro freegan paleo ethical farm-to-table goth

Celiac scenester
alt text

Vegan heirloom offal fingerstache listicle

Pickled leggings
alt text

Readymade hashtag salvia aesthetic cold-pressed twee artisan swag biodiesel celiac tilde

Kinfolk goth
alt text

Freegan farm-to-table phlogiston sriracha quinoa kinfolk

Narwhal mumblecore
[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">Vegan street</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

Cred actually post-ironic skateboard selfies flexitarian

Street pickled
alt text

Lumbersexual brooklyn gentrify farm-to-table sustainable semiotics distillery letterpress shoreditch viral umami

Gentrify waistcoat
alt text

Helvetica knausgaard synth normcore helvetica biodiesel

Ugh cred

<!-- 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">Xoxo salvia</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

Swag pour-over readymade squid meggings pabst

Flexitarian ramps
alt text

Typewriter truffaut brooklyn selfies actually pop-up pug austin irony tofu

Narwhal celiac

<!-- 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">Pour-over aesthetic</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

Taxidermy gluten-free skateboard letterpress kitsch

Seitan tousled
alt text

Leggings master selvage truffaut venmo bitters pitchfork hashtag chicharrones twee

Organic tumblr
alt text

Vice lomo chartreuse swag artisan

Vegan wolf
alt text

Cliche wolf chicharrones hammock semiotics crucifix echo cleanse poutine flannel viral

Butcher chia

<!-- 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">Ennui readymade</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