1.6.0 • Published 2 years ago

swiffy-slider v1.6.0

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

Tweet

npm.io version npm version CSS gzip size CSS Brotli size JS gzip size JS Brotli size

Super fast carousel and slider with touch for optimized websites running in modern browsers.

Modern browser offers really good options these days to create much better user experience for sliders and carousels than existing libraries offer.

This project utilizes what is available in modern browsers resulting in a super lightweight and fast slider, greatly reducing the javascript footprint and increase performance to meet todays standards.

  • Navigate with Touch, Keyboard, trackpad, pen and Mouse - because it is just browser scrolling
  • Uses native browser scroll behavior, scroll-snap and CSS grid to provide the best mobile and touch experience
  • Can run in CSS only mode - no js for even better performance
  • SEO friendly - all content is in pure markup
  • WCAG friendly - all content is in pure markup and can be annotated accordingly, supports tabbing, keyboard navigation, aria attributing and all what is needed.
  • Setup is done in pure markup and css classes, no scripting required
  • No js loading of slides, configuration or initialization
  • Vanilla javascript, less than 1.3kb ~110 lines
  • Very low overall footprint ~3.5kb in total (css+js gzip'ed)

Quick start

1. Add CSS and JS to website head section

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

2. Add markup

<div class="swiffy-slider slider-item-helper">
    <ul class="slider-container">
        <li>Slide 1</li>
        <li>Slide 2</li>
        <li>Slide 3</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>

Swiffy Slider script automatically binds to all .swiffy-slider instances

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

Loading (ESM)

// 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"

Read the Getting started page for examples, configuration options and a visual configurator.

Features

  • Carousel - Slide any content. Images, cards, videos, text, banners, posters, anything markup
  • Carousel - Slide using touch, keyboard, mouse or navigation buttons
  • Carousel - 1, 2, 3, 4, 5 or 6 slides visible in the slider wrapper
  • Carousel - snap to start or center slide items
  • Carousel - Slide one item or entire page on navigate when showing more than one
  • Carousel - Partially reveal next and previous (optional) slide to indicate touch scroll is available
  • Carousel - Loop to start when slides end
  • Navigation - 7 built in navigation styles for next and previous navigation in light or dark mode, 14 in total
  • Navigation - Overlay or outside navigation options
  • Navigation - Show navigation arrows on hover or always. Show on desktop, but not touch
  • Indicators - 3 built in indicator styles; pin, dots or squares in light or dark mode
  • Indicators - Overlay or outside location of indicators
  • Indicators - Navigate to slide by clicking indicator
  • Auto play - Automatically slide with specified interval
  • Auto pause - Stop playing when mouse is hovering carousel or touch is used
  • Animation - Add animations when slides slide into view
  • Animation - Choose between 6 different animations
  • Animation - Use normal, fast or slow animations
  • Scripting - Automatic or manual initialization of slider instances using swiffyslider.init or swiffyslider.initSlider
  • Scripting - Execute scripts when an item is done sliding using swiffyslider.onSlideEnd
  • Scripting - Start and stop automatic sliding using script

What's included

Within the download you'll find the following directories and files. You'll see something like this:

swiffy-slider/
├── dist/
│   ├── css/
│   │   ├── swiffy-slider.css
│   │   ├── swiffy-slider.min.css.map
│   │   ├── swiffy-slider.min.css.map
│   ├── js/
│   │   ├── swiffy-slider-extensions.js
│   │   ├── swiffy-slider-extensions.min.js
│   │   ├── swiffy-slider-extensions.min.js.map
│   │   ├── swiffy-slider.esm.js
│   │   ├── swiffy-slider.esm.min.js
│   │   ├── swiffy-slider.esm.min.js.map
│   │   ├── swiffy-slider.js
│   │   ├── swiffy-slider.min.js
│   │   ├── swiffy-slider.min.js.map
├── src/
│   ├── swiffy-slider.extensions.js
│   ├── swiffy-slider.css
│   ├── swiffy-slider.esm.js
│   ├── swiffy-slider.js

The download contains compiled and minified CSS and JS (swiffy-slider.min.*). source maps (swiffy-slider.*.map) are available for use with certain browsers' developer tools.

Bugs and feature requests

Have a bug or a feature request? Check out the issues section and see if your issue or idea is already created. If your problem or idea is not addressed yet, please open a new issue.

Documentation

Swiffy slider documentation website is part of this repo and can be found in the docs folder. Visit the doc on our github documentation page

Introduction

Swiffy slider is a wrapper defined in html with slides, navigation and indicators as its children.

All options and behavior is controlled with css classes that is added to the wrapper. No js configuration.

The wrapper is the .swiffy-slider element - options to control layout and behavior of slides, navigation and indicators are added to this element.

Markup structure

The slider markup is a .swiffy-slider wrapper that has 3 sections.

  • One .slider-container that contains the slides
  • Two .slider-nav buttons that is navigation buttons previous and next (optional)
  • One .slider-indicators that contains the indicators (optional)
<div class="swiffy-slider [slider options] [navigation options] [indicator options]" data-slider-nav-autoplay-interval="3000">
    <ul class="slider-container">
        <li>Slide 1</li>
        <li>Slide 2</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>                
    </div>    
</div>

This example uses ul>li for slides. Can also be i.e. div or other elements. This example uses button for navigation. Could also be divs, but cannot be ul>li as that would be nested. This example uses div>button for indicators but could be other elements, i.e. ul>li structure instead. Wether to use buttons or div for the navigating elements, depends on how WCAG needs to be handled.

Slider options (CSS Classes)

Options are the css classes that can be added to the .swiffy-slider element to control how the slider will look and behave. No config in JS or similar.

The example below use the .slider-item-show2 option to show 2 slides and .slider-item-reveal to reveal part of the next and previous slide. By adding additional classes behavior and layout is controlled.

Head over to the configurator to try all options

<div class="swiffy-slider slider-item-show2 slider-item-reveal">
    <ul class="slider-container">
        <li>Slide 1</li>
        <li>Slide 2</li>
        <li>Slide 3</li>
    </ul>
</div>

Slider wrapper

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

Slider sections

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

Slider options

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

Navigation options

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

Indicator options

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

Animation options

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

Javascript

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.

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(&#39;load&#39;, () =&gt; {
    const sliderElement = document.getElementById(&#39;myslider&#39;);
    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 &gt;= 0 &amp;&amp; slideScrollRightPosition &lt;= 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".

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.

Example

<div class="swiffy-slider slider-item-reveal 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>...</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 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

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

Limitations

These limitations are known and intentionally there to keep this library small, fast and smooth.

  • Scroll speed comes in 2 flavors - instant or 'smooth'. This is because that is what browsers support out of the box using CSS scroll-behavior. See MDN
  • Does not support slides of uneven widths. The width is controlled by the width of the wrapper and can have 1-6 slides per page depending on configuration.
  • Smooth scrolling is not supported out of the box in Safari (Before v 15.4) (iOS + Mac) but can be fixed using a polyfill. See polyfill
  • RTL is untested but as the entire slider is just markup, it should be supported very well
  • Works in 'modern' browsers from the last ~3 years only. No IE support or anything funny.

Use other sliders and carousels if these limitations is important in your project.

Contributing

You are more than welcome to contribute by opening issues and create pull requests. Keep in mind that this project is meant to be very simple in nature and support recent browsers only.

This project is not going into a race of adding as many features as possible - but quite the opposite. Performance and filesize has high priority.

The general rule is, that Swiffy Slider is covering the most common usages, and that more exotic usages are made in examples. If not at least 50% of all installations need a feature, the feature probably belong somewhere else.

Examples of more exotic use cases are more than welcome as part of the examples, so please create pulls for that.

Open tasks that you could help with:

  • Svelte component
  • Vue component
  • React component

Thank you for your understanding.

Star gazers

Feel free to star this project and help spread the word.

Stargazers repo roster for @dynamicweb/swiffy-slider

Examples of sites using Swiffy Slider

Send an email to https://github.com/nicped if you would like your site on this list.

Versioning

See the Releases section of our GitHub project for changelogs for each release version of Swiffy Slider.

Creators

Nicolai Høeg Pedersen

Dynamicweb

Copyright and license

Code and documentation copyright 2022 the Swiffy Slider Authors and Dynamicweb A/S Code released under the MIT License. Docs released under Creative Commons.

1.6.0

2 years ago

1.5.3

2 years ago

1.5.2

2 years ago

1.5.1

2 years ago

1.5.0

2 years ago

1.2.0

2 years ago

1.4.1

2 years ago

1.4.0

2 years ago

1.3.1

2 years ago

1.3.0

2 years ago

1.1.0

2 years ago

1.0.2

3 years ago

1.0.1

3 years ago

1.0.0

3 years ago