Swiffy Slider documentation

Get started with Swiffy Slider

Quick start and try out Swiffy Slider using jsDelivr and basic markup. Complete documentation of css classes and javascript API.

Use the configuration page to get UI assitance to setup a slider and see the results instantly.

Configurator

Quick start

Installation options, configuration options and scripting of the Swiffy Slider

CSS and Javascript

Copy-paste the stylesheet <link> and javascript <script> into your <head> section.

<script src="https://cdn.jsdelivr.net/npm/swiffy-slider@1.6.0/dist/js/swiffy-slider.min.js" crossorigin="anonymous" defer></script>
<link href="https://cdn.jsdelivr.net/npm/swiffy-slider@1.6.0/dist/css/swiffy-slider.min.css" rel="stylesheet" crossorigin="anonymous">

HTML

Copy-paste the HTML below into the <body> of your markup.

<div class="swiffy-slider">
    <ul class="slider-container">
        <li><img src="https://source.unsplash.com/49b9l_29ceA/1600x900" style="max-width: 100%;height: auto;"></li>
        <li><img src="https://source.unsplash.com/nKAglN6HBH8/1600x900" style="max-width: 100%;height: auto;"></li>
        <li><img src="https://source.unsplash.com/E9ZwWcMGzj8/1600x900" style="max-width: 100%;height: auto;"></li>
    </ul>

    <button type="button" class="slider-nav"></button>
    <button type="button" class="slider-nav slider-nav-next"></button>

    <div class="slider-indicators">
        <button class="active"></button>
        <button></button>
        <button></button>
    </div>
</div>
        

Safari smooth scrolling polyfill

UPDATE: Safari 15.4 introduces smooth scrolling, see release notes https://developer.apple.com/documentation/safari-release-notes/safari-15_4-release-notes

Sliding the carousel on touch devices using fingers are not affected by this issue.

When sliding using buttons, indicators and javascript, the new slides are shown instantly with no smoothing when using Safari. In Safari based browsers, smooth scrolling is not supported because it is still lacking browser support. See Can I use

If you want to support smoooth scrolling on Safari based browsers, add this polyfill to your head section

Copy-paste the javascript <script> into your <head> section.

<script src="https://unpkg.com/smoothscroll-polyfill/dist/smoothscroll.min.js" crossorigin="anonymous" defer></script>

Additional installation options

Download the latest release

Clone the repo:

git clone https://github.com/dynamicweb/swiffy-slider.git

Install with npm

npm install swiffy-slider

Install with yarn

yarn add swiffy-slider

Load Swiffy slider using webpack, ESBuild and other build tools.
NOTE: Swiffy slider is an ES Module and you need a supported processing ECMAScript compiler - i.e. webpack 5+ etc.


// import Swiffy Slider JS
import { swiffyslider } from 'swiffy-slider'
window.swiffyslider = swiffyslider;

window.addEventListener("load", () => {
    window.swiffyslider.init();
});

// import Swiffy Slider CSS
import "swiffy-slider/css"

CSS classes and options

Change behavior and styles on slides, navigation and indicators by adding option css classes to the .swiffy-slider wrapper.

CSS class Description
swiffy-slider The overall wrapper of the slider instance. Should be a block element. Can contain 3 different things as direct children; slider-container, slider-indicators and slider-nav

Slider sections

For possible child elements to the swiffy-slider wrapper. These sections adds slides, navigation and indicators

CSS class Description
slider-container
  • Creates the scrollable container that holds the slides
  • Can be any element and is a CSS grid
  • Using a ul>li structure for the container and slides provides good semantics
  • The direct descendants of this element are the slides them selves and can hold any markup
  • The width of the slides are controlled by the slider options. Default is 100% width
  • Can be styled using slider-item-* options
slider-nav
slider-nav-next
  • Creates a navigation button
  • Should be button element and there should be exactly 2
  • Default is a left button
  • Add slider-nav-next to make the next button
  • Can be styled using slider-nav-* options
slider-indicators
  • Creates a container for indicator buttons
  • The direct descendants of this element are the indicators. Add active for the active indicator for first load
  • Descendants should be button elements and there should be one button per slide or per page when showing more than one slide
  • Can be styled using slider-indicators-* options

Slider options

For the swiffy-slider wrapper. The slider-item-* option classes affects the slides (The slider-container children)

CSS class Description
slider-item-show2
slider-item-show3
slider-item-show4
slider-item-show5
slider-item-show6
Shows 2, 3, 4, 5 or 6 slides at a time in the slider wrapper. Each slide is either 1/2, 1/3, 1/4, 1/5 or 1/6 of the slider wrapper width.
slider-item-show2-sm Shows 2 slides at a time in the slider wrapper when in small viewport. By default show2-5 will show only one slide when in viewports less than 62rem (992px in most cases). With this option it shows 2 in small viewports
slider-item-reveal Reveals some of previous and next slide. Each slide is either 1/1, 1/2, 1/3, 1/4 or 1/6 of the slider wrapper width minus a little to reveal next and previous slides
slider-item-ratio Enables ratio sizing of the slide elements. Default ratio is 2:1 or 50% meaning the slides have half the heigh of their width. This option sets object-fit:cover; on first element inside the slide element - to stretch images to fill out the slide box and keep aspect ratio.
slider-item-ratio-32x9
slider-item-ratio-21x9
slider-item-ratio-2x1
slider-item-ratio-16x9
slider-item-ratio-4x3
slider-item-ratio-1x1
slider-item-ratio-3x4
Controls the slide ratio when ratio is enabled. Default ratio is 2:1 or 50% meaning the slides have half the heigh of their widt.
slider-item-ratio-contain Sets the content of a ratio enabled slide to have object-fit:contain; instead of default object-fit:cover;. This ensures that if the content of the slide is an image or embedded video, it is scaled down so all is visible within the slide box.
slider-item-nogap Removes the horisontal gap between slides
slider-item-snapstart Snaps slides to start of the slider wrapper instead of center when using .slider-item-reveal
slider-item-nosnap Removes auto snapping for slides so they slide freely. Primarily have an affect on touch devices as navigating with arrows and indicators is per slide or per page
slider-item-nosnap-touch Same effect as slider-item-nosnap but only on devices that has a primary input which is not a mouse, i.e. mobile media (hover: none)
slider-item-first-visible Use with .slider-nav-autohide to hide the previous navigation arrow when the slider loads. Will automatically be removed or added when first slide is not or is visible
slider-item-last-visible Use with .slider-nav-autohide to hide the next navigation arrow when the slider loads. Will automatically be removed or added when last slide is not or is visible
slider-item-helper For debugging: Adds a test layout to slide items; minimum height, background color, centers content and background. Meant for testing and should be removed in real code

Navigation options

For the swiffy-slider wrapper. The slider-nav-* option classes affects the slider-nav elements

CSS class Description
slider-nav-page Slides entire page when showing more than one slide item on the slider wrapper. Default behavior moves just one slide to the left or right
slider-nav-noloop Disables slider loop - so when on first/last slide navigate previous/next does not take the user to the last/first slide
slider-nav-nodelay Disables smooth scrolling when sliding using navigation buttons, indicators and autoplay. Makes the new slide or page appear instantly with no scroll smoothing. Does not affect touch navigation
slider-nav-autoplay Automatically slide to next slide or next page in intervals. Default is 2500 ms = 2.5s
data-slider-nav-autoplay-interval attribute Changes the default autoplay interval - value is in ms. data-slider-nav-autoplay-interval="3000". Default value is 2500, minimum value is 750 ms
slider-nav-autopause Stops and restarts the autoplay when mouse is hovering the slider wrapper or when it is touched on touch devices. Will restart on mouseout, but not when touch ends
slider-nav-round
slider-nav-square
slider-nav-arrow
slider-nav-chevron
slider-nav-caret
slider-nav-caretfill
Changes the default navigation chevrons to an alternative navigation style using different arrows
slider-nav-touch Shows navigation buttons on touch devices. By default navigation buttons are hidden on touch devices using the media (hover: none) query. By adding this option, the navigation buttons are always visible on touch devices
slider-nav-visible Makes the nav buttons visible always. By default navigation buttons are hidden until the slider wrapper is hovered
slider-nav-outside Moves the navigation buttons outside the slider wrapper and shrinks the width of the slider wrapper accordingly (by 3 or 5 rem on each side depending on navigation style)
slider-nav-outside-expand Moves the navigation buttons outside the slider wrapper by applying negative margins (-3 or -5 rem) so the slides and wrapper keeps their size. The navigation buttons overlays surrounding content.
slider-nav-scrollbar Makes the scrollbar for the .slider-container visible. Acts as indicator and navigation if running in css only mode. On touch devices the scrollbar is not shown when not sliding because that is how the browser behaves
slider-nav-dark Changes the navigation buttons to a dark version. Black arrows or black circle with white arrows
slider-nav-autohide Will hide appropiate navigation arrow when the first or last slide is visible to indicate that sliding is at its start or end. On load the arrow will first disappear when the script is loaded. Also add .slider-item-first-visible class to the .swiffy-slider instance together with .slider-nav-autohide to hide the start arrow on load before js executes.

Indicator options

For the swiffy-slider wrapper. The slider-indicators-* option classes affects the slider-indicators child elements

CSS class Description
slider-indicators-round Changes the default indicators to a circle
slider-indicators-square Changes the default indicators to a square
slider-indicators-outside Moves the indicator buttons under the slider wrapper and increases the height of the slider wrapper but not the slides them selves
slider-indicators-dark Changes the indicator buttons to a dark version
slider-indicators-highlight Hightlights the active indicator even more by increasing its size
slider-indicators-sm Shows indicator buttons on small devices under 992px in width. By default indicator buttons are hidden on small devices. By adding this option, the indicators buttons are always visible. Since the number of indicators and number of slides does not match on small devices when showing more than one item per page, do not use this option in that case

Animation options

For the swiffy-slider wrapper. The slider-nav-animation-* option classes affects the animation of slides when they slide into view.

CSS class Description
slider-nav-animation Enables animation on slides. An animation effect class is also required for animation to be enabled
slider-nav-animation-appear Apear animation using opacity and scale - starting from 30% opacity and a 90% scale
slider-nav-animation-fadein Fade in animation using opacity - starting from 50% opacity. Can be combined with .slider-nav-animation-scale/scaleup
slider-nav-animation-scale Scale up animation using scale - starts with 90% size. Can be combined with .slider-nav-animation-fadein
slider-nav-animation-scaleup Scale up animation using scale - starts with 25% size. Can be combined with .slider-nav-animation-fadein
slider-nav-animation-turn Turn animation using rotateY - starts with 70deg ratotation
slider-nav-animation-slideup Slide up animation using translateY - starts at 60% of the height
data-slider-nav-animation-threshold attribute Changes the default animation threshold - value is between 0-1. data-slider-nav-animation-threshold="0.3". Default value is 0.3. This setting defines how many percent of a slide should be visible before the animation starts

Custom animations

It is possible to create custom animation using css tranform and opacity.


.slider-nav-animation.slider-nav-animation-mycustomanimation .slider-container>*>* {
    transform: translateY(80%) scale(.90) rotateY(90deg);
    opacity: 0.1;
}

<div class="swiffy-slider slider-nav-animation slider-nav-animation-mycustomanimation">
...
<div>
                        
                        

Mouse drag options

For the swiffy-slider wrapper. The .slider-nav-mousedrag option class enables mouse dragging if extensions is included

Requires swiffy-slider-extensions.js script - see further down.

CSS class Description
.slider-nav-mousedrag Enables mouse dragging. Should not be used when showing more than one slide per page.

Javascript API

The Swiffy Slider script can be accessed using window.swiffyslider or simply swiffyslider

All options and behavior is handled by the css classes, so using the scripts directly is only for more advanced scenarios.

Method Description
swiffyslider.version; Needs no explanation :-)
swiffyslider.init(rootElement = document.body); Initializes all instances of .swiffy-slider elements and binds events to handle navigation, indicators and autoplay. By default document.body is searched for instances, but can be limited further to i.e. content area (and skip header, navigation, footer etc) to further improve init performance.
swiffyslider.initSlider(sliderElement); Initializes one instance of swiffy slider wrapper. The passed element has to be a .swiffy-slider element
swiffyslider.slide(sliderElement, next = true); Slides to the next slide or next page depending on the nav settings. The passed slider element has to be a .swiffy-slider element. By default this method slides next, but call it with false to slide to previous
swiffyslider.slideToByIndicator(); This method is called when an indicator button is clicked. Should not be called directly. Instead call slideTo
swiffyslider.slideTo(sliderElement, slideIndex); Slides to the specified slide (index starts with 0 for first slide). The passed slider element has to be a .swiffy-slider element.
swiffyslider.onSlideEnd(sliderElement, delegate, timeout = 125); Provide a callback/delegate function to get called when sliding ends. The default timeout is 125ms and should not be too low as it could cause the delegate to be called more than once on each scroll. The passed slider element has to be a .swiffy-slider element.
swiffyslider.autoPlay(sliderElement, timeout, autopause); Manually starts autoplay for a container using the specified timeout. Autopause can be enabled. Usually auto play is handled using css option classes. This method can be used to start autoplay when the slider scrolls into view or similar. The passed slider element has to be a .swiffy-slider element.
swiffyslider.handleIndicators(sliderElement); Manually updates the indicators active state to reflect the current position of the slider. The passed slider element has to be a .swiffy-slider element.

Listening for sliding ends for a container

<script>
const sliderElement = document.getElementById('myslider');
swiffyslider.onSlideEnd(sliderElement, function() {
    console.log('Scrolling stopped');
});
</script>

Listening for sliding ends for a container and find visible slides

<script>
window.addEventListener('load', () => {
    const sliderElement = document.getElementById('myslider');
    swiffyslider.onSlideEnd(sliderElement, function() {
        const visibleSlideElements = getVisibleSlides(sliderElement);
        const visible = [];
        for (const slide of visibleSlideElements) {
            visible.push(slide.innerText);
        }
        console.log(visible);
        console.log(visibleSlideElements);
    });
});

function getVisibleSlides(sliderElement) {
    const container = sliderElement.querySelector('.slider-container');
    //returns an array of slide elements that are fully or partially visible
    const visibleSlides = [];
    //We are using a grid layout and the slides left and right properties include the width of the gap, so when comparing with container width add a gap for each side of the slide gap.
    const gapWidth = parseInt(window.getComputedStyle(container).columnGap);
    for (const slide of container.children) {
        var slideScrollLeftPosition = slide.getBoundingClientRect().left - container.getBoundingClientRect().left;
        var slideScrollRightPosition = slideScrollLeftPosition + slide.offsetWidth - gapWidth;
        if (slideScrollLeftPosition >= 0 && slideScrollRightPosition <= container.offsetWidth) {
            visibleSlides.push(slide);
        }
    }
    return visibleSlides;
}
</script>

Javascript loading and binding

Load Swiffy slider using webpack, ESBuild and other build tools. In your index.js (or whatever you call it).
NOTE: Swiffy slider is an ES Module and you need a supported processing ECMAScript compiler - i.e. webpack 5+ etc.


// import Swiffy Slider JS
import { swiffyslider } from 'swiffy-slider'
window.swiffyslider = swiffyslider;

window.addEventListener("load", () => {
    window.swiffyslider.init();
});

// import Swiffy Slider CSS
import "swiffy-slider/css"

// import Swiffy Slider src CSS unminified
import "swiffy-slider/src/swiffy-slider.css"

Avoid autobinding by adding data-noinit attribute on the script tag and then attach the slider manually

<script src="https://cdn.jsdelivr.net/npm/swiffy-slider@1.6.0/dist/js/swiffy-slider.min.js" data-noinit defer>
<script>
    window.addEventListener('load', () => {
        //Use only one of the loading options below!
        //loads all sliders
        swiffyslider.init();
        //loads specific slider
        swiffyslider.initSlider(document.getElementById('myslider'));
    });
</script>
<div class="swiffy-slider" id="myslider">
  <div class="slider-container">
    <div></div>
  </div>
  ...
</div>
<script src="https://cdn.jsdelivr.net/npm/swiffy-slider@1.6.0/dist/js/swiffy-slider.min.js" data-noinit defer>
    <script>
        window.addEventListener('load', () => {
            //loads all sliders in main and skip header and footer search for increased init performance.
            swiffyslider.init(document.getElementById('content'));
        });
    </script>
    <header>...</header>
    <main id="content">
      <div class="swiffy-slider" id="myslider">
        <div class="slider-container">
          <div></div>
        </div>
        ...
      </div>
    </main>
    <footer>...</footer>

Load as module using ES version of the script

<script type="module">
    import {swiffyslider} from 'https://cdn.jsdelivr.net/npm/swiffy-slider@1.6.0/dist/js/swiffy-slider.esm.min.js'; 
    window.swiffyslider = swiffyslider; 
    window.swiffyslider.init(); 
</script>

Load as ES module on demand, here using load - could be when slider scrolls into view or navigation arrow is clicked the first time. Load module and initialize sliders.

<script>
window.addEventListener("load", () => {
    import ('https://cdn.jsdelivr.net/npm/swiffy-slider@1.6.0/dist/js/swiffy-slider.esm.min.js').then((swiffysliderModule) => {
        swiffysliderModule.swiffyslider.init();
    });
});
</script>

Load as ES module on demand. Load module and assign to window for later script manipulation of slides

<script>
window.addEventListener("load", () => {
    import ('https://cdn.jsdelivr.net/npm/swiffy-slider@1.6.0/dist/js/swiffy-slider.esm.min.js').then((swiffysliderModule) => {
        window.swiffyslider = swiffysliderModule.swiffyslider;
        window.swiffyslider.init();
    });
});
</script>

Optimized loading

When loading the script with defer attribute, the initialization will happen as soon as the script is downloaded. Deferred scripts are requested and run as soon as the document is parsed by the browser. This is the recommended approach.

<script src="https://cdn.jsdelivr.net/npm/swiffy-slider@1.6.0/dist/js/swiffy-slider.min.js" defer>
If the script is loaded without defer attribute, the initialization will happen when document.readyState === 'interactive' using a document.onreadystatechange event listener. The script will load and run before the Dom is loaded, but has been parsed.
<script src="https://cdn.jsdelivr.net/npm/swiffy-slider@1.6.0/dist/js/swiffy-slider.min.js">

The above approach ensures the sliders are initialized as soon as possible and earlier in the page life cycle compared to using load or DOMContentLoaded events. This might not always be optimal depending on what else is running on the page. Since the content of Swiffy Slider is always markup and is rendered when the markup is parsed and does not change when initialized, a later loading of the script and initialization of the sliders could be a benefit to leave more power for more important scripts. See "Load as ES module on demand".

Javascript extensions

Some features of Swiffy Slider is not considered core functionality and is in a seperate js library to keep loading as small as possible.

Extensions are available in swiffy-slider-extensions.js

The Swiffy Slider Extension script can be accessed using window.swiffyslider.extensions or simply swiffyslider.extensions

Method Description
swiffyslider.extensions.version; Needs no explanation :-)
swiffyslider.extensions.init(rootElement = document.body); Initializes all instances of .swiffy-slider elements and enables their extensions if available. Works on these classes: .slider-nav-mousedrag
swiffyslider.extensions.initSlider(sliderElement); Initializes one instance of swiffy slider wrapper. The passed element has to be a .swiffy-slider element
swiffyslider.extensions.handleMouseDrag(e, sliderElement); Attaches the events that handles mouse drag. Automatically called from init. Can be called manually like this: sliderElement.addEventListener("mousedown", (e) => swiffyslider.handleMouseDrag(e, sliderElement), { passive: true });
Load Swiffy slider main script, css and extensions script
<script src="https://cdn.jsdelivr.net/npm/swiffy-slider@1.6.0/dist/js/swiffy-slider.min.js" crossorigin="anonymous" defer></script>
<script src="https://cdn.jsdelivr.net/npm/swiffy-slider@1.6.0/dist/js/swiffy-slider-extensions.min.js" crossorigin="anonymous" defer></script>
<link href="https://cdn.jsdelivr.net/npm/swiffy-slider@1.6.0/dist/css/swiffy-slider.min.css" rel="stylesheet" crossorigin="anonymous">

CSS variables

The Swiffy Slider CSS is making use of a number of CSS variables that can be overriden to control behavior and styling

Slide sizes, ratios, navigation etc. can be controlled by overruling the variable on the .swiffy-slider instance or in custom css.

Variable Example Description
--swiffy-slider-item-width --swiffy-slider-item-width:75%; Calculated based on the number of slides shown, the gap, reveal etc. Should not be overriden. INFO If needed, it has to be overriden on the .slider-container element.
--swiffy-slider-item-gap --swiffy-slider-item-gap:25px; Changes the gap between slides when enabled. Default --swiffy-slider-item-gap is 1rem, but can be any valid CSS mesurement. The --swiffy-slider-item-gap is part of the calculation of --swiffy-slider-item-width
--swiffy-slider-item-reveal --swiffy-slider-item-reveal:20%; Changes the width of the reveal of next and previous slides when enabled. Default --swiffy-slider-item-reveal is 8rem if previous and next is revealed and 4rem if only next is revealed (if .slider-item-snapstart is in use). The --swiffy-slider-item-reveal is part of the calculation of --swiffy-slider-item-width
--swiffy-slider-item-ratio --swiffy-slider-item-ratio:100/33.3 Sets the ratio to a custom value. Use with .slider-item-ratio and omit use of any .slider-item-ratio-* classes
--swiffy-slider-item-count --swiffy-slider-item-count:8; Sets the number of slides to show - same as using .slider-item-show{n} but can i.e. be set to a number higher than 6 if needed.
--swiffy-slider-nav-light --swiffy-slider-nav-light:lightcyan; Sets the light color for navigation arrows. Default is #fff. Use to control the color of light navigation. Square and Round navigation use both colors - one for backgrond, the other for arrow color.
--swiffy-slider-nav-dark --swiffy-slider-nav-dark:darkolivegreen; Sets the dark color for navigation arrows. Default is #333. Use to control the color of dark navigation. Square and Round navigation use both colors - one for backgrond, the other for arrow color. Can be any color variable.
--swiffy-slider-nav-zoom --swiffy-slider-nav-zoom:1.25; Use to overrule the navigation arrow sizes. Default is 1.0 for normal sizes and .75 for small sized navigation. Set to i.e. 1.25 to make navigation arrows larger.
--swiffy-slider-track-opacity --swiffy-slider-track-opacity:0.25; Sets the scrollbar track opacity when scrollbar is displayed
--swiffy-slider-track-height --swiffy-slider-track-height:1rem; Sets the scrollbar track height. Default is .5rem if scrollbar (.slider-nav-scrollbar) is enabled.

Example

<div class="swiffy-slider slider-item-ratio slider-nav-round slider-nav-visible" 
    style="
    --swiffy-slider-item-ratio:100/33.3;
    --swiffy-slider-nav-light:lightcyan;
    --swiffy-slider-nav-dark:darkolivegreen;
    --swiffy-slider-nav-zoom:85%;
    --swiffy-slider-item-reveal:25%;">
    <ul class="slider-container">
        <li><img src="https://source.unsplash.com/49b9l_29ceA/1600x900" style="max-width: 100%;height: auto;"></li>
        <li><img src="https://source.unsplash.com/nKAglN6HBH8/1600x900" style="max-width: 100%;height: auto;"></li>
        <li><img src="https://source.unsplash.com/E9ZwWcMGzj8/1600x900" style="max-width: 100%;height: auto;"></li>
    </ul>

    <button type="button" class="slider-nav"></button>
    <button type="button" class="slider-nav slider-nav-next"></button>

    <div class="slider-indicators">
        <button class="active"></button>
        <button></button>
        <button></button>
    </div>
</div>
                                        
  • ...
  • ...
  • ...
  • ...
  • ...
  • ...