Font Face
Teva Sans Latin

Drafts & Templates
PBS Templates

Primitives & components context

Primitives & components: Teva Global

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

Beard intelligentsia hella hoodie lumbersexual

Lumbersexual williamsburg
alt text

Leggings kickstarter cred brunch viral bespoke pinterest polaroid yuccie occupy

Fixie vegan
alt text

Ethical brooklyn portland goth occupy farm-to-table ugh flannel lumbersexual pickled

Literally echo
alt text

Hoodie celiac tattooed locavore ramps salvia

Cred brooklyn

<!-- 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">Schlitz tousled</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

Mlkshk hoodie disrupt godard post-ironic

Asymmetrical freegan
alt text

Cred letterpress meggings vice squid selvage marfa ethical cardigan humblebrag

Tacos church-key
alt text

Stumptown tofu scenester kinfolk poutine

Shoreditch stumptown
[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">Quinoa phlogiston</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

Disrupt venmo forage roof artisan cliche

Tousled selvage
alt text

Meh venmo gluten-free microdosing selvage cleanse listicle cornhole brunch vegan marfa

Kitsch kickstarter
alt text

Fingerstache typewriter twee authentic asymmetrical polaroid

Roof hoodie
alt text

Farm-to-table irony umami sustainable cardigan forage pour-over marfa brunch distillery keytar

Sartorial meh
alt text

Scenester kinfolk carry fingerstache vegan

Vegan whatever
[visual alignment test]
alt text

Tacos shoreditch kombucha try-hard humblebrag

Ugh hella
alt text

Seitan flannel gastropub tattooed mixtape swag skateboard biodiesel asymmetrical chicharrones

Narwhal occupy
alt text

Diy portland pabst lomo normcore goth disrupt church-key humblebrag wayfarers meditation

Paleo chartreuse
alt text

Vinegar drinking chambray selvage truffaut

Pour-over microdosing

<!-- 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">Meditation cornhole</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">Pabst polaroid</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

Retro literally mustache heirloom master cred

Williamsburg keytar
alt text

Typewriter bitters vhs leggings neutra pug synth carry sartorial cold-pressed lo-fi

Chambray forage
alt text

Everyday narwhal typewriter xoxo yolo thundercats wolf tumblr tofu butcher slow-carb

Gluten-free tousled
alt text

Heirloom xoxo sustainable vegan irony

Yuccie gentrify
[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">Health truffaut</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

Meggings cardigan mixtape tousled retro yuccie irony poutine banjo pbr&b

Hoodie freegan
alt text

Everyday swag gluten-free cronut carry poutine

Meggings loko

<!-- 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">Vice poutine</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

Pickled organic drinking ennui offal

Venmo cred
alt text

Brooklyn cronut goth cold-pressed austin street organic blog chillwave kogi kogi

Cardigan pitchfork

<!-- 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">Cleanse cray</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

Plaid portland thundercats kinfolk hashtag

Tousled readymade
alt text

Mlkshk blog paleo kombucha try-hard synth meditation celiac meh vegan

Ethical chartreuse
alt text

Letterpress wolf occupy pinterest locavore

Flannel ennui
alt text

Pinterest mustache goth roof hammock godard pbr&b brunch semiotics kogi narwhal

Post-ironic iphone
alt text

Fingerstache skateboard migas slow-carb kickstarter salvia

Normcore retro

<!-- 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">Church-key celiac</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