Keen SliderSimplistic's Version


Documentation

Last updated: 01/01/22

keen-slider is a very lightweight library for carousels that has a very smooth and natural touch feeling.

Made ADA COMPLIANT by Simplistic, adding features like navigation with the keyboard and indicating the corresponding elements that can be on focus. We have also introduced other custom features in the base code to allow our Theme to support certain configurations that do not come by default in the library.

Installation

Include in your Theme the latest keen_slider.js and keen_slider.css files that can be found in the latest version of Simplistic's Theme.

Usage

keen-slider will be initialized on a container, and the direct children of that container must be the slides.

We suggest to stick to the following HTML structure and classes to make sure it works properly:

      <div class="keen"> <!-- this wrapper is not required, but the Arrows/Dots/navBar should be inside this wrapper for default styling -->
  <div class="keen-slider"> <!-- this is the required container, where the library is initialized. Use the class "keen-slider" for default styling -->
    <div class="keen-slider-slide"> <!-- the direct children of the container must be the slides -->
      This is a slide.
    </div><!-- Do NOT include any other element inside the container, only the slides -->
  </div>
  <button class="keen-arrow prev"> <!-- the BACK arrow need the "keen-arrow prev" classes for default styling. Arrows can be moved around inside the .keen wrapper -->
    {% include 'icons', icon: 'arrow-left' %}
  </button>
  <button class="keen-arrow next"> <!-- the NEXT arrow need the "keen-arrow next" classes for default styling. Arrows can be moved around inside the .keen wrapper -->
    {% include 'icons', icon: 'arrow-left' %}
  </button>
  <div class="keen-dots"></div> <!-- optional (when dots are enabled), use this class for default styling. This element can be moved around inside the .keen wrapper -->
  <div class="keen-nav-bar"></div> <!-- optional (when navBar is enabled), use this class for default styling. This element can be moved around inside the .keen wrapper -->
</div>

    
var slider = document.querySelector(".keen-slider"); // be more specific like "#shopify-section-{{section.id}} .keen-slider"
new KeenSlider(slider, {
  mode: "free-snap",
  loop: true,
  slidesPerView: 2.25,
  dots: '.keen-dots', // be more specific like "slider.closest('.keen').querySelector('.keen-dots')" or "#shopify-section-{{section.id}} .keen-dots"
  navBar: '.keen-nav-bar', // be more specific...
  prevButton: '.keen-arrow.prev', // be more specific...
  nextButton: '.keen-arrow.next' // be more specific...
});

Options

Option Description
autoAdjustSlidesPerView
New feature by simplistic: July 2021
Type: boolean
Default: false
When the slides available are LESS than the slidesPerView (aka. there are not enough slides to fill the space of the first page), and this option is set to "true", the slides will be forced to enlarge and fill all the available space.
automove
New feature by simplistic: December 2021
Type: number
Default: 0
This option will move the slides automatically at a constant pace. The value entered here is the speed of the movement (normally between 1 and 4, 1 being slow and 4 fast). Accepts decimals.
Example
autoplay
New feature by simplistic: July 2021
Type: number
Default: 0
This option will activate the "Next" action to move the slider automatically after a given interval of time. The value entered here is the interval, in seconds. It accepts decimals.
Example
breakpoints
Type: object
Default: undefined
Changes the options or event hooks for a given breakpoint by overriding the options at the root level. Each key has to be a valid media query string e.g. '(orientation: portrait) and (min-width: 500px)'. Each value has to be an object with options and/or event hooks. Note: If multiple media queries match, the last one is applied. See the example below:
Example:
                new KeenSlider('#my-slider', {
  loop: true,
  breakpoints: {
    '(min-width: 720px) and (max-width: 1000px)': {
      loop: false,
    }
  }
})
              
centered
Type: boolean
Default: false
Active slide will be centered - only makes sense when slidesPerView is greater than 1
controls
Type: boolean
Default: true
Control slider with mouse or touch gestures
customAnimation
New feature by simplistic: September 2021
Type: string
Default: false
The word entered as value will be added as a class to the slider wrapper (unless it's 'false'). The animation for 'fade' is ready to use (comes by default in the stylesheet). More custom CSS animations can be added to the stylesheet.
Important: this option will make the slides be one over each other (with position: absolute) instead of one next to each other. Therefore, you may also want to add the property setContainerHeight to true to auto calculate the height of the slider (based on the height of its slides), otherwise you must set a height with css to the .keen-slider element.
Example:
                new KeenSlider('#my-slider', {
  customAnimation: 'fade',
  setContainerHeight: true,
  slidesPerView: 1,
  mode: 'snap',
  loop: true
})
              
Example
dots
New feature by simplistic: July 2021
Type: object
Default: false
Injects the dots to the element indicated as value. The element must be empty because its inner HTML will be replaced.
Example:
                new KeenSlider('#my-slider', {
  slidesPerView: 1,
  mode: 'snap',
  loop: true,
  dots: '#shopify-section-{{section.id}} .keen-dots'
})
              
Example
drag
New feature by simplistic: December 2021
Type: boolean
Default: true
Enables or disables mouse and touch control.
dragSpeed
Type: number
Default: 1
Adjust the speed that is translated to the slider when dragging - minus values would invert the swipe direction
duration
Type: number
Default: 500
Set the animation duration for the "snap"-mode
initial
Type: number
Default: 0
Index of the initial activated slide
loop
Type: boolean
Default: false
Infinite loop of slides
mode
Type: "snap" | "free-snap" | "free"
Default: "snap"
Sets the mode of movement of the slider
navBar
New feature by simplistic: December 2021
Type: object
Default: false
Injects the navigation bar to the element indicated as value. The element must be empty because its inner HTML will be replaced.
Example:
                <div class="keen-nav-bar"></div>

              
                new KeenSlider('#my-slider', {
  slidesPerView: 1,
  mode: 'free-snap',
  loop: true,
  navBar: '#shopify-section-{{section.id}} .keen-nav-bar'
})
              
Example
navBarType
New feature by simplistic: December 2021
Type: "scroll" | "progress"
Default: scroll
Sets the type of navigation bar.
Important: the "progress" bar will not work correctly on infinite carousels, it just makes sense for sliders that have a begining and ending. So please set the option loop to false if you want to use the progress bar.
Example:
                new KeenSlider('#my-slider', {
  slidesPerView: 1,
  mode: 'free-snap',
  navBar: '#shopify-section-{{section.id}} .keen-nav-bar',
  navBarType: "progress",
  loop: false
})
              
Example of both types
nextButton
New feature by simplistic: July 2021
Type: object
Default: false
Indicates which element from the DOM will trigger the NEXT function (scrolling the quantity of slides set in the slidesToScroll option).
Example:
                <button class="keen-arrow next">
  {% include 'icons', icon: 'arrow-right' %}
</button>

              
                new KeenSlider('#my-slider', {
  slidesPerView: 1,
  mode: 'free-snap',
  loop: true,
  prevButton: '#shopify-section-{{section.id}} .keen-arrow.prev',
  nextButton: '#shopify-section-{{section.id}} .keen-arrow.next'
})
              
Example
prevButton
New feature by simplistic: July 2021
Type: object
Default: false
Indicates which element from the DOM will trigger the PREV function (scrolling the quantity of slides set in the slidesToScroll option).
Example:
                <button class="keen-arrow prev">
  {% include 'icons', icon: 'arrow-left' %}
</button>

              
                new KeenSlider('#my-slider', {
  slidesPerView: 1,
  mode: 'snap',
  loop: true,
  prevButton: '#shopify-section-{{section.id}} .keen-arrow.prev',
  nextButton: '#shopify-section-{{section.id}} .keen-arrow.next'
})
              
Example
pauseOnHover
Type: boolean
Default: true
Will pause the movement (autoplay or automove) when you hover the mouse over the slider.
Example
preventEvent
Type: string
Default: "data-keen-slider-pe"
Name of the attribute that prevents the events from the slider on the element
resetSlide
Type: boolean
Default: false
Reset to initial when the breakpoint changes
rtl
Type: boolean
Default: false
Set the direction in which the slides are positioned to right-to-left
rubberband
Type: boolean
Default: true
Noticeable when the slider is NOT on the loop mode. Adds a bouncing effect when you reach the beginning or the end of the slider and try to keep scrolling in that direction. This effect is automatically turned OFF when you're scrolling with the mouse or trackpad on desktop (to prevent a bad UX).
setContainerHeight
New feature by simplistic: July 2021
Type: boolean
Default: false
Automatically gets the height of the taller slide, and sets it to the .keen-slider element (the parent of the slides). This is useful for custom animations like Fade, where the slides are positioned with "positon: absolute", therefore the container needs to have a defined height (but it's ooptional, you can also set the height of the .keen-slider manually with css).
slides
Type: DOMString | Function | HtmlElement[] | number
Default: ".keen-slider-slide"
  • DomString
  • Function, that return HtmlElement[]
  • HtmlElement[]
  • number - for custom sliders, see the examples for use cases
slidesActiveClass
New feature by simplistic: July 2021
Type: string
Default: active
The value entered will be set as css class of the active slide.
slidesPerView
Type: number
Default: 1
Number of slides per view. It accepts decimals, such as 2.5 (two slides and a half will be visible per page).
slidesToScroll
New feature by simplistic: July 2021
Type: number
Default: 1
Number of slides to scroll when the "Next" button is pressed. It accepts decimals, such as 2.5 (two slides and a half will be visible per page).
spacing
Type: number
Default: 0
Spacing between slides in pixel
vertical
Type: boolean
Default: false
Set the slider direction to vertical
wheel
New feature by simplistic: December 2021
Type: boolean
Default: true
Enables/disables the scrolling the ability to move the slider using the wheel of the mouse or the scrolling geatures of the trackpad. When disabled, you can still move it freely by drag/drop with your mouse or trackpad, but not with the scrolling wheel or gesture.
Example of disabled wheel

Event hooks

The following event hooks are available and can be set during initialization, just like the options. Every event hook comes with the instance of the slider.

Example:
        new KeenSlider('#my-slider', {
  created: slider => {
    console.log(slider.details())
  }
})
      
Event Description
afterChange is fired after an animation is finished or the slider position is changed externally or internally
beforeChange is fired before an animation is finished or the slider position is changed externally or internally
mounted is fired after the slider is mounted to a container and the events are initialized
created is fired after the slider has been initialized for the first time
slideChanged is fired when the currently visible slide has changed
dragEnd is fired when the dragging of the container has ended
dragStart is fired when the dragging of the container has started
move is fired every time the slider changes the position
destroyed is fired after the slide is destroyed

Methods

Event Description
controls
Param: active(boolean)
Activate or deactivate touch or mouse controls of the slider
details
Returns the internal details of the slider See the examples for use cases
Example Return:
                // zero point - left edge of the intended position of the active slide
{
  absoluteSlide: 100, // absolute index of the current slide - if loop is active, this number can be higher as the number slides or smaller the zero
  relativeSlide: 5, // relative index of the current slide - will be a number between 0 and the number of slides
  direction: 1, // last direction of slider movement: 1 | 0 | -1
  progressTrack: 0, // current progress of slider regarding to the track: 0 to 1
  progressSlides: 0, // current progress of slider regarding to the slides: 0 to 1
  positions: [ // position details of each slide
    {
      distance: 0, // relative distance to the start of the viewport, in relation to the width of the viewport
      portion: 1 // portion of visiblity of the slide - 0 to 1
    },
    ...
  ],
  position: 10000, // absolute position of the slider track (distance to the zero point) in px - length of the slider is infinite
  speed: 0, // current movement speed in px/ms
  size: 5, // number of slides
  widthOrHeight: 100 // width or height, if vertical, of the slider
}
              
moveToSlide
Param: slide(number) duration(number)
Move to given slide (absolute slide - track is infinite when loop is active!) - optionally with the duration of the animation
moveToSlideRelative
Param: slide(number) nearest(boolean) duration(number)
Move to given slide (relative slide - Range 0...n-1 - n is the number of slides)
  • nearest - move optionally in the direction of the nearest element (for the loop)
  • duration - set the duration of the animation, optionally
next Move to next slide
prev Move to previous slide
refresh
Param: options(object)
Reinitialize slider and optionally overwrite options
resize Manually trigger a resize - to recalculate width/height of slides or when a new slide was added
destroy Remove events and styles set by the slider - refresh() would undo this

ExamplesKeen Slider - Simplistic's Version


Slides Per View

Numeric value, accepts decimals.

var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
  slidesPerView: 2.25,
  mode: "free-snap",
  loop: true,
  dots: '.keen .keen-dots',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next'
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Slides To Scroll

Numeric value, accepts decimals (but should be a round number to keep the same structure when moving the slider).

var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
  slidesPerView: 3.25,
  slidesToScroll: 3,
  mode: "free-snap",
  loop: true,
  dots: '.keen .keen-dots',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next'
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Alignment of the Slides (Left or Center)

Left Aligned (default)

var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
  mode: "free-snap",
  loop: true,
  slidesPerView: 2,
  dots: '.keen .keen-dots',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next'
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Center Aligned

var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
  centered: true,
  mode: "free-snap",
  loop: true,
  slidesPerView: 2,
  dots: '.keen .keen-dots',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next'
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Center Aligned with Animation

Knowing that the centered slide has the class "active", we could create an animation like this:

.keen-slider-slide .wrap {transform: scale(0.8); opacity: 0.5;}
.keen-slider-slide.active .wrap {transform: scale(1); opacity: 1;}
var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
  centered: true,
  mode: "snap",
  loop: true,
  slidesPerView: 2,
  dots: '.keen .keen-dots',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next'
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Vertical

Top aligned (default)

The .keen-slider element of a Vertical slider must have a height set.

.keen-slider {height: 30em;}
var slider = document.querySelector(".keen .keen-slider");
var sliderObj = new KeenSlider(slider, {
  vertical: true,
  mode: "free-snap",
  loop: true,
  slidesPerView: 2,
  dots: '.keen .keen-dots',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next',
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Center aligned

The .keen-slider element of a Vertical slider must have a height set.

.keen-slider {height: 30em;}
.keen .keen-dots {position: absolute; top: 0; right: 1em; width: auto; height: 100%; margin: 0;}
var slider = document.querySelector(".keen .keen-slider");
var sliderObj = new KeenSlider(slider, {
  vertical: true,
  centered: true,
  mode: "free",
  loop: true,
  slidesPerView: 2,
  dots: '.keen .keen-dots',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next',
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Loop

Example of Loop turned off:

var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
  mode: "free-snap",
  loop: false,
  slidesPerView: 2.25,
  dots: '.keen .keen-dots',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next'
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Rubberband

Noticeable when the slider is NOT on the loop mode. Adds a bouncing effect when you reach the beginning or the end of the slider and try to keep scrolling in that direction (similar effect as in iOS).

This effect is automatically turned OFF when you're scrolling with the mouse or trackpad on desktop (to prevent a bad UX). Try dragging-dropping with the mouse instead, or scrolling on a mobile phone, to notice the difference between true/false.

Rubberband TRUE (default):

var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
  rubberband: true,
  mode: "free-snap",
  loop: false,
  slidesPerView: 2.25,
  navBar: '.keen .keen-nav-bar',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next'
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Rubberband FALSE:

var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
  rubberband: false,
  mode: "free-snap",
  loop: false,
  slidesPerView: 2.25,
  navBar: '.keen .keen-nav-bar',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next'
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Spacing

Although the spacing is added between all the slides, the first and last slides will get to the edge of the carousel container, so it's easier to match the design.

var slider = document.querySelector(".keen .keen-slider");
var sliderObj = new KeenSlider(slider, {
  spacing: 15,
  mode: "free-snap",
  loop: true,
  dots: '.keen .keen-nav-bar',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next'
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Padding-left on mobile (with loop)

If we want to apply a padding/offset on the left side on a LOOPING carousel (infinite), we will have to set the spacing option to 0 in the javascript, and set a padding-left to the items in css.

Designers: please note that the separation between the edge of the viewport and the first slide, must be the same as the separation between each slide (not larger, not smaller).

.keen .keen-slider-slide {padding-left: 15px;}
.keen .keen-arrows,
.keen .keen-dots {padding-left: 15px;}
var slider = document.querySelector(".keen .keen-slider");
var sliderObj = new KeenSlider(slider, {
  spacing: 0,
  mode: "free-snap",
  loop: true,
  slidesPerView: 1.25,
  dots: '.keen .keen-dots',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next'
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Please note: If you don't mind that the carousel DOESN'T LOOP (isn't infinite), we have more flexibility for the paddings. Then you can apply this solution where we play with the overflows.


Shadow on slides

Problem:

The shadow of the slides gets cut off on the edges of the carousel. This happens because the .keen-slider element (the parent of the slides) has overflow: hidden, and we can't remove that. We can't even add a padding to the .keen-slider element because it will mess up the calculations of the next/prev steps.

Solution:



.keen .keen-slider {margin: 0 -10px;}
.keen .keen-slider-slide {padding: 10px;}
.keen .keen-slider-slide .wrap {box-shadow: 4px 4px 9px rgb(0,0,0,0.5);}
var slider = document.querySelector(".keen .keen-slider");
var sliderObj = new KeenSlider(slider, {
  spacing: 0,
  mode: "free-snap",
  loop: true,
  slidesPerView: 3,
  dots: '.keen .keen-dots',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next'
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Scrolling Modes

The difference is more noticeable on Mobile Phones or when you move the carousel with drag-and-drop with the mouse.

Snap Mode

The slides will scroll based on the number set for slidesToScroll (default: 1), and at the end of the animation they will adjust/snap to match the original position settings.

var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
   mode: "snap",
   loop: true,
   spacing: 15,
   slidesPerView: 2,
   dots: '.keen .keen-dots',
   prevButton: '.keen .keen-arrow.prev',
   nextButton: '.keen .keen-arrow.next'
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Free Mode

The slides will scroll freely based on the strength and length of the scrolling movement, and at the end of the animation they will stay exactly where you left them (even if they're not symmetric).

var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
   mode: "free",
   loop: true,
   spacing: 15,
   slidesPerView: 2,
   dots: '.keen .keen-dots',
   prevButton: '.keen .keen-arrow.prev',
   nextButton: '.keen .keen-arrow.next'
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Free-Snap Mode

The slides will scroll freely based on the strength and length of the scrolling movement, and at the end of the animation they will adjust/snap to match the original position settings.

var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
   mode: "free-snap",
   loop: true,
   spacing: 15,
   slidesPerView: 2,
   dots: '.keen .keen-dots',
   prevButton: '.keen .keen-arrow.prev',
   nextButton: '.keen .keen-arrow.next'
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Wheel / Trackpad scrolling

The option 'wheel' turns on/off the ability to move the slider using the wheel of the mouse or the scrolling geatures of the trackpad. When disabled, you can still move it freely by drag/drop with your mouse or trackpad, but not with the scrolling wheel or gesture. It's set to true by default, let's disable it in this example:

var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
   wheel: false,
   mode: "free",
   loop: true,
   spacing: 15,
   slidesPerView: 2,
   dots: '.keen .keen-dots',
   prevButton: '.keen .keen-arrow.prev',
   nextButton: '.keen .keen-arrow.next'
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Numeric Nav, instead of dots

We can achieve this by enabling the dots, and adding the numbers with a CSS counter.

.keen-dots {counter-reset: line-number 0;}
.keen-dots-dot {counter-increment: line-number 1;}
.keen-dots-dot:after {content: counter(line-number, decimal);}
var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
  mode: "free-snap",
  loop: true,
  spacing: 15,
  slidesPerView: 2,
  dots: '.keen .keen-dots',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next'
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Navigation Bar

Just add a div with class "keen-nav-bar" in the HTML wherever you want the bar to be displayed, and then add the option navBar to the script pointing to that element.

Then you can choose the type of bar with the option navBarType ("progress" or "scroll").

NavBar type Scroll

<div class="keen-nav-bar"></div>
var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
  mode: "free",
  spacing: 15,
  loop: true,
  slidesPerView: 2,
  navBar: '.keen .keen-progress-bar',
  navBarType: 'scroll',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next' 
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

NavBar type Progress

Please note that

<div class="keen-nav-bar"></div>
var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
  mode: "free",
  spacing: 15,
  loop: false,
  slidesPerView: 2,
  navBar: '.keen .keen-progress-bar',
  navBarType: 'progress',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next' 
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Vertical with Nav Bar

The .keen-slider element of a Vertical slider must have a height set.

The nav bar must be placed next to the slider with css or helper classes.

.keen-slider {height: 30em;}
var slider = document.querySelector(".keen .keen-slider");
var sliderObj = new KeenSlider(slider, {
  vertical: true,
  mode: "free-snap",
  slidesPerView: 2,
  loop: false,
  navBar: '.keen .keen-nav-bar',
  navBarType: 'scroll',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next',
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Breakpoints

This option changes the options for a given breakpoint by overriding the options at the root level.

var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
  mode: "free",
  spacing: 15,
  loop: true,
  dots: '.keen .keen-dots',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next' 
  breakpoints: {
    '(min-width: {{settings.breakpoint_tablet | plus: 1}}px)': {
        slidesPerView: 2.25,
  		center: false
    },
    '(min-width: {{settings.breakpoint_mobile | plus: 1}}px) and (max-width: 900px)': {
        slidesPerView: 2,
  		centered: true
    },
    '(max-width: {{settings.breakpoint_mobile}})': {
        slidesPerView: 1.25,
  		centered: true,
      	spacing: 0
    }
  }
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Hide dots or arrows on different Breakpoints

You can hide them with CSS, or using the corresponding Helper CSS Classes on the elements (such as: large--show medium-down--hide, large--hide medium-down--show).

In this example we're hiding the dots and arrows on Tablets and Mobile:

<!-- Use the helpers to hide the arrows or dots on the corresponding breakpoint. -->
<button class="keen-arrow prev medium-down--hide">
    [...]
</button>
<button class="keen-arrow next medium-down--hide">
    [...]
</button>
<div class="keen-dots medium-down--hide"></div>
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Destroy/Kill on different Breakpoints

The destroy() function will remove everything that was added by the library (the elements inside the keen-dots, the styles that were added to the slides automatically (min-width, max-width, transform), etc.

But the classes that already existed in the document will NOT be removed on destroy() (keen, keen-slider, keen-slider-slide, keen-dots, keen-arrow, etc) . If we want the classes to be removed on destroy (mainly .keen-slider and .keen-slider-slide which are the ones that may cause troubles), those elements should not have the classes by default, and we should add them via javscript afterwards.

We should also show/hide the arrows and dots in the corresponding breakpoints using the Helper CSS classes.

In this example the items are displayed in a grid on Desktop and Tablet, and as a Slider on Mobile.

<div class="keen">
  <!-- replace the keen-slider and keen-slider-slide classes with different ones -->
  <div class="items-wrapper">
    <div class="item">
      [...]
    </div>
  </div>
  <!-- use the CSS helper classes to show/hide the arrows and dots in the corresponding breakpoint -->
  <button class="keen-arrow prev hide medium-down--show">
    [...]
  </button>
  <button class="keen-arrow next hide medium-down--show">
    [...]
  </button>
  <div class="keen-dots hide medium-down--show"></div>
</div>
var slider;
var sliderObj;
var itemsWrapper = document.querySelector('.keen .items-wrapper');

function initSlider() {
  // Add the keen classes to the corresponding elements
  itemsWrapper.classList.add('keen-slider');
  itemsWrapper.querySelectorAll(':scope > div').forEach((item)=>{;
    item.classList.add('keen-slider-slide')
  });

  // Init the keen slider
  slider = document.querySelector(".keen .keen-slider");
  sliderObj = new KeenSlider(slider, {
    spacing: 15,
    mode: "free",
    loop: true,
    slidesPerView: 2.25,
    dots: '.keen .keen-dots',
    prevButton: '.keen .keen-arrow.prev',
    nextButton: '.keen .keen-arrow.next',
    breakpoints: {
      '(max-width: {{settings.breakpoint_mobile}})': {
          slidesPerView: 1.5,
          centered: true,
     	  spacing: 0
      }
    }
  });
  
  // Optional, remove the classes that make the elements display as a grid:
  itemsWrapper.classList.remove('grid');
  itemsWrapper.querySelectorAll(':scope > div').forEach((item)=>{
    item.classList.remove('grid-item', 'one-third')
  });
}

function destroySlider() {
  // Destroy the keen slider:
  if(sliderObj) {
    sliderObj.destroy();
    sliderObj = false;
  }

  // Remove the keen classes to the elements:
  itemsWrapper.classList.remove('keen-slider');
  itemsWrapper.querySelectorAll(':scope > div').forEach((item)=>{
    item.classList.remove('keen-slider-slide');
  });
  
  // Optional, add the classes that make the elements display as a grid:
  itemsWrapper.classList.add('grid');
  itemsWrapper.querySelectorAll(':scope > div').forEach((item)=>{
    item.classList.add('grid-item', 'one-third')
  });
}

function updateSlider() {
  if($s.media.isSmall) {
    initSlider();
  } else {
    destroySlider();
  }
}
window.addEventListener('mediaChange', updateSlider);
updateSlider();
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Custom Animation

The word that we pass to the customAnimation option will be set as a class on the keen-slider element.

The property setContainerHeight: true, is required so that the slides can take up the corresponding space (otherwise they will not show up cause they have position: absolute on this mode).

Fade

The styles for a "fade" effect is already included in the keen_slider.css, therefore if you set customAnimation to "fade", that effect will automatically be applied.

var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
  customAnimation: 'fade',
  setContainerHeight: true,
  slidesPerView: 1,
  mode: "snap",
  loop: true,
  dots: '.keen .keen-dots',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next'
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Zoom or other custom Slide animations

Knowing that the active slide always have the class "active", we can apply any custom animations by our own to the stylesheet, either to the slides themselves or to the inner elements, for example, for a "zoom" animation we could do the following:

@keyframes zoomIn {
  0%{opacity:0;transform:scale(0.8);}
  100%{opacity:1;transform:none}
}
@keyframes fadeOut {
  0%{opacity:1;}
  100%{opacity:0;}
}
.keen-slider.custom-animation.zoom .keen-slider-slide {animation-name: fadeOut;}
.keen-slider.custom-animation.zoom .keen-slider-slide.active {animation-name: zoomIn;}
var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
  customAnimation: 'zoom',
  setContainerHeight: true,
  slidesPerView: 1,
  mode: "snap",
  loop: true,
  dots: '.keen .keen-dots',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next'
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Slide and Zoom

If we want the slides to zoom in/out when they slide in/out instead of staying put, it's even easier. Do not use the customAnimation option, just do it with css.

Keep in mind that in this case the animation should be applied not to the keen-slider-slide object but to its inner content (because the slide is already being animated differently for the sliding movement):

.keen-slider .keen-slider-slide .wrap {-webkit-transform: scale(0.8); transform: scale(0.8);}
.keen-slider .keen-slider-slide.active .wrap {-webkit-transform: scale(1); transform: scale(1);}
var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
  slidesPerView: 1,
  mode: "snap",
  loop: true,
  dots: '.keen .keen-dots',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next'
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Animation for the inner elements

Or leave the default Slide animation (remove the customAnimation and setContainerHeight properties) and apply an effect to the inner elements of the Active slides like this:

@keyframes fadeInUp {
    0%{opacity:0;transform:translate3d(0,50%,0)}
    100%{opacity:1;transform:none}
}
@keyframes fadeOut {
  0%{opacity:1;}
  100%{opacity:0;}
}
.keen-slider-slide .title {animation-name: fadeOut; animation-delay: 0.2s; animation-duration: 1s; animation-fill-mode: both;}
.keen-slider-slide .btn {animation-name: fadeOut; animation-delay: 0.5s; animation-duration: 1s; animation-fill-mode: both;}
.keen-slider-slide.active .title,
.keen-slider-slide.active .btn {animation-name: fadeInUp;}
var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
  slidesPerView: 1,
  mode: "snap",
  loop: true,
  dots: '.keen .keen-dots',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next'
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Autoplay

The value is the interval in seconds (accepts decimals).

var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
  autoplay: 1,
  pauseOnHover: false,
  slidesPerView: 1.5,
  centered: true,
  mode: "snap",
  loop: true,
  dots: '.keen .keen-dots',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next'
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Automove

The value is the scrolling speed (normally between 1 and 4, 1 being slow and 4 fast). Accepts decimals.

var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
  automove: 1,
  pauseOnHover: true,
  slidesPerView: 1.5,
  centered: true,
  mode: "snap",
  loop: true,
  dots: '.keen .keen-dots',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next'
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Applying left offset with .container-left

Difference between .container .container-left and .container-right

Inspect these elements with the console to understand how the margin and paddings work:

.container
.container-left
.container-right

A slider that aligns to the left container, but has the full-screen area to scroll:

Important:

For this example, we will have to play with the overflow of the section and the keen-slider. This option doesn't work with Loop carousels (it would have a glitch at the end), but it doesn't really make sense with loop anyway.

.my-section-wrapper {overflow: hidden;}
.keen-slider {overflow: visible;}
      <div class="container-left container-right"> <!-- wrap the slider in a div with the .container-left class to set up the container only on the left side (while the right side reaches the edge of the screen), that's what you will see initially. Then also add the .container-right class too so that when the slider reaches the end, it aligns to the right side of the container too. This last piece is optional, but desired. -->
  <div class="keen-slider"> 
    <div class="keen-slider-slide">
      This is a slide.
    </div>
  </div>
</div>

    
var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
  loop: false, /* This is required for this demo */
  mode: "free",
  spacing: 15,
  navBar: '.keen .keen-nav-bar',
  navBarType: 'progress',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next',
  breakpoints: {
    '(min-width: {{settings.breakpoint_tablet | plus: 1}}px)': {
      slidesPerView: 3
    },
    '(max-width: {{settings.breakpoint_tablet}})': {
      slidesPerView: 1.25
    }
  }
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button

Cutting off on the left side

This is easier, and it can be on Loop mode. No additional CSS required, other than the helper class .container-left

Take a look (and compare it with the example above to understand the differences):

      <div class="container-left container-right"> <!-- wrap the slider in a div with the .container-left class to set up the container only on the left side (while the right side reaches the edge of the screen), that's what you will see initially. Then also add the .container-right class too so that when the slider reaches the end, it aligns to the right side of the container too. This last piece is optional, but desired. -->
  <div class="keen-slider"> 
    <div class="keen-slider-slide">
      This is a slide.
    </div>
  </div>
</div>

    
var slider = document.querySelector(".keen .keen-slider");
new KeenSlider(slider, {
  loop: true, /* Compared to the previous example, this can be true (it won't glitch), though for this example I will use "false" to compare easily with the previous example */
  mode: "free",
  spacing: 15,
  dots: '.keen .keen-dots',
  prevButton: '.keen .keen-arrow.prev',
  nextButton: '.keen .keen-arrow.next',
  breakpoints: {
    '(min-width: {{settings.breakpoint_tablet | plus: 1}}px)': {
      slidesPerView: 3.35
    },
    '(max-width: {{settings.breakpoint_tablet}})': {
      slidesPerView: 1.25
    }
  }
});
Slide 1
Button
Slide 2
Button
Slide 3
Button
Slide 4
Button
Slide 5
Button
Slide 6
Button
Slide 7
Button
Slide 8
Button