Accessible Touch-friendly Range Slider Plugin - noUiSlider

File Size: 97.9 KB
Views Total: 42624
Last Update:
Publish Date:
Official Website: Go to website
License: MIT
Accessible Touch-friendly Range Slider Plugin -  noUiSlider

noUiSlider is a Lightweight and Customisable plugin for creating really cool, touch-friendly Range Sliders without having to include the complete jQuery UI library. 

Every slider can have two handles to select a range, a fixed minimum or maximum can be set to select a limit, or two handles can be used, to simply pick some points.

Every event in the noUiSlider has an optional callback, so you can completely control any slider interaction. There is also some cool math in the read-out functions, so you can dynamically calculate any selected value. 

It supports touch on capable devices, such as iPhone, iPad and Android phones and tablets. 

The plugin currently works as a Vanilla JavaScript plugin since v8.0.1 (No jQuery Required).

You Might Also Be Interested In:

Basic Usage (Create a range slider):

1. Install & Download the library with package managers.

# Yarn
$ yarn add nouislider

$ npm install nouislider --save

2. Or download the zip and Include the noUiSlider.js and noUiSlider.css on the page.

<link href="/dist/nouislider.min.css" rel="stylesheet">
<script src="/dist/nouislider.min.js"></script>

3. Create a container to hold the range slider.

<div class="noUiSlider"></div>

4. Initialize the plugin and generate a basic range slider:

var mySlider = document.getElementById('noUiSlider');

noUiSlider.create(slider, {
  // options here

5. All possible options to customize the range slider.

noUiSlider.create(slider, {

  // Start values
  start: [20, 80],

  // Min/Max values
  range: {
    'min': [0],
    'max': [100]

  // Margin in pixels
  margin: 30,

  // Padding in pixels
  padding: [10, 15],

  // Limits the maximum distance between two handles
  limit: 40,

  // Step size
  step: 10,

  // Forces the slider to jump between the specified values
  snap: false,
  // Controls the bar between the handles or the edges of the slider.
  // Pass an array with a boolean for every connecting element, including the edges of the slider. The length of this array must match the handle count + 1.
  // Setting true sets the bars between the handles, but not between the handles and the sliders edges.
  connect: false,

  // "ltr", "rtl"
  direction: "ltr",

  // accepts a "-" separated list of "drag", "tap", "fixed", "snap", "unconstrained" or "none"
  // e.g. "drag-fixed", "unconstrained-tap", "hover"
  behaviour: "tap",

  // "vertical" or "horizontal"
  orientation: "horizontal",

  // Enable Tooltips.
  // boolean, Formatter, array of boolean or Formatter for each handle
  tooltips: [false, wNumb({decimals: 1}), true],

  // Enable animation
  animate: false,
  animationDuration: 300,

  // Enables keyboard interactions
  keyboardSupport: true,

  // add aria-label to noUiHandler
  handleAttributes: false,

  // CSS prefix
  cssPrefix: "noUi-",

  // keyboard interactions
  keyboardPageMultiplier: 5,
  keyboardMultiplier: 1,
  keyboardDefaultStep: 10

  // When moving the slider through documents, or in other advanced scenarios, the documentElement that events are bound to can be changed.
  documentElement: documentElement,

  // Format the slider output
  format: {
    // 'to' the formatted value. Receives a number.
    to: function (value) {
        return value + ',-';
    // 'from' the formatted value.
    // Receives a string, should return a number.
    from: function (value) {
        return Number(value.replace(',-', ''));

  // Used for the aria-valuenow accessibility attribute
  ariaFormat: wNumb({
    decimals: 3

  // Default classes
  cssClasses: {
    target: "target",
    base: "base",
    origin: "origin",
    handle: "handle",
    handleLower: "handle-lower",
    handleUpper: "handle-upper",
    touchArea: "touch-area",
    horizontal: "horizontal",
    vertical: "vertical",
    background: "background",
    connect: "connect",
    connects: "connects",
    ltr: "ltr",
    rtl: "rtl",
    textDirectionLtr: "txt-dir-ltr",
    textDirectionRtl: "txt-dir-rtl",
    draggable: "draggable",
    drag: "state-drag",
    tap: "state-tap",
    active: "active",
    tooltip: "tooltip",
    pips: "pips",
    pipsHorizontal: "pips-horizontal",
    pipsVertical: "pips-vertical",
    marker: "marker",
    markerHorizontal: "marker-horizontal",
    markerVertical: "marker-vertical",
    markerNormal: "marker-normal",
    markerLarge: "marker-large",
    markerSub: "marker-sub",
    value: "value",
    valueHorizontal: "value-horizontal",
    valueVertical: "value-vertical",
    valueNormal: "value-normal",
    valueLarge: "value-large",
    valueSub: "value-sub"

6. API methods:

// destroy 

// get steps

// get slider value

// set slider value

// set handle
// number: zero-indexed handle number
// string: slider value
// boolean: fire an event
slider.noUiSlider.setHandle("number", "string", boolean);

// reset

// update options

// generate points along the slider

// remove pips

// remove tooltips

// get positions

7. Event handlers:

  • update
  • slide
  • set
  • change
  • start
  • end
// slider.noUiSlider.on(..., ...);

slider.noUiSlider.on('', function (values, handle, unencoded, tap, positions, noUiSlider) {
  // in the 'one' namespace


v15.4.0 (2021-08-15)

  • Added: handleAttributes option
  • Added: drag-all behaviour
  • Added: ESM/ES6 module distribution dist/nouislider.mjs
  • Added: support for ranges where min = max
  • Added: getPositions method
  • Fixed: Duplicate change/set events when using snap behaviour

v15.3.0 (2021-08-11)

  • Added: keyboardMultiplier option

v15.2.0 (2021-06-16)

  • Added: unencoded boolean argument to get method to return raw slider values
  • Added: support for "partial" formatters in pips.format, ariaFormat and tooltips options

v15.1.1 (2021-05-20)

  • Fixed: tooltips option accepts one Formatter for all tooltips

v15.1.0 (2021-05-09)

  • Added: drag event when dragging connecting elements

v15.0.0 (2021-05-02)

  • noUiSlider is now written and distributed as TypeScript;
  • Types are now provided. If you are currently using @types/nouislider, this should be replaced;
  • The distributed files have moved from distribute to dist in the NPM package, and are no longer in the repository; You may need to change the path to the noUiSlider CSS file if you are importing it using a package manager;
  • Fixed: Slider now properly works in multiple layers of Shadow DOM;
  • Removed: version from exceptions and export;
  • Removed: Bower support;

v14.7.0 (2021-04-07)

  • noUiSlider is now build with Typescript. This release contains no further changes.

v14.6.4 (2021-03-18)

  • Fixed: Fixed updateOptions with falsy value for start

v14.6.3 (2020-11-19)

  • Fixed: Fixed removing namespaced event listeners, internal listeners getting removed

v14.6.2 (2020-09-16)

  • Fixed: Ignore erroneous mouse events on taps for iOS 13.4 
  • Added: exactInput argument to set and setHandle methods

v14.6.1 (2020-08-17)

  • Fixed: Pips in count mode ignores pip at end of range

v14.6.0 (2020-06-28)

  • Added: keyboardPageMultiplier and keyboardDefaultStep options
  • Fixed: Ignore erroneous tap events for iOS

v14.5.0 (2020-05-12)

  • Added: Support for margin, padding and limit on non-linear sliders

v14.4.0 (2020-05-07)

  • Added: getOrigins and getTooltips methods;
  • Added: Default styling to support merging overlapping tooltips;
  • Doc updated

v14.3.0 (2020-05-05)

  • Added: Default cssClasses are now exposed and can be modified
  • Fixed: Destroying sliders with multiple classes in cssClasses fails 

v14.2.0 (2020-03-28)

  • Added: Slider api as event parameter
  • Added: Allow multiple classes in cssClasses option
  • Fixed: Slider not working within shadow DOM
  • Fixed: Last pip not rendered if it is also the first and at the slider edge

v14.1.1 (2019-12-15)

  • Fixed: Text direction is not correctly determined when the slider is not in the DOM

v14.1.0 (2019-12-04)

  • Fixed: Styling requires a root html node, so noUiSlider can't be used in shadow dom
  • Added: Support for PageUp/PageDown and Home/End keys in keyboard support

v14.0.3 (2019-06-28)

  • Fix slider constraints on init conditions

v14.0.2 (2019-06-28)

  • Fixed: Keyboard interaction uses formatter when it does not need to

v14.0.1 (2019-06-22)

  • Fixed: Visual regression in Safari

v14.0.0 (2019-06-20)

  • Fixed: change & slide events should fire on keyboard control
  • Fixed: .noUi-origin overflows document on vertical sliders
  • Fixed: Clicking to right of handle doesn't move it when it's at the same point as another
  • Added: Additional documentation on number formatting

v13.1.5 (2019-04-25)

  • Fixed: Full-range padding

v13.1.4 (2019-03-20)

  • Fixed: Keyboard interaction does not work with snap option

v13.1.3 (2019-03-15)

  • Fixed: Keyboard interaction allows handles to "push" other handles
  • Fixed: Update event fires for all handles during keyboard interaction

v13.1.2 (2019-03-14)

  • Fixed: Handle disappears in Safari on tap
  • Fixed: Disabled slider still accepts keyboard interaction

v13.1.1 (2019-02-14)

  • Fixed: Slider hang when using a zero-length range

v13.1.0 (2019-02-08)

  • Fixed: Updating pips using updateOptions
  • Added: Updating tooltips using updateOption

v13.0.0 (2019-02-07)

  • Added: Built-in keyboard support
  • Added: .noUi-touch-area element
  • Fixed: Dragging a range does not check for handle disabled state
  • Fixed: Incorrect CSS transform in pips

v12.1.0 (2018-10-26)

  • Added: unconstrained behaviour
  • Added: setHandle API

v12.0.0 (2018-09-14)

  • Change: License changed to MIT;
  • Change: Build process is now based on NPM scripts, phasing out the Grunt task runner.
  • Fixed: Aria values are now as per spec;
  • Change: Pips formatting are now written as HTML;
  • Change: The filter option is now called for all pips;
  • Added: The filter option can now return -1 to hide a pip;
  • Added: keyboardSupport option;
  • Added: documentElement option;

v11.1.0 (2018-04-24)

  • Change: null options are now handled consistently
  • Fixed: Missing transform origin in IE9
  • Fixed: padding on one side of the slider could not exceed 50%

v11.0.2 (2018-01-21)

  • Change: Use CSS transforms for handle movement, resulting in a massive performance improvement;
  • Change: Support multitouch by default;
  • Change: Handle stacking is now on .noUi-origin instead of .noUi-handle;
  • Added: A .noUi-connects element holding all .noUi-connect elements;
  • Added: [data-value] property for .noUi-value in pips;
  • Added: padding option can now take an array for different padding values at both sides of a slider;
  • Removed: useRequestAnimationFrame option. No longer needed with CSS transforms;
  • Removed: multitouch option. Now enabled by default;
  • Fixed: Slider could ignore end events it should handle;
  • Fixed: Stop depending on array type;
  • Fixed: set method might bypass margin option;
  • Fixed: Alignment of pips for RTL sliders;
  • Fixed: Several issues regarding pips;
  • Fixed: Slider ignores clicks on .noUi-target outside of .noUi-base;
  • Fixed: .noUi-origin moving out of the page causes horizontal scrolling;
  • Fixed: Relative .noUi-handle has unintended margin;

v10.0.0 (2017-07-10)

  • Change: Change event listeners to be passive;
  • Fixed: Pips are now updated when calling updateOptions;
  • Fixed: Content Security Policy issue with pips;
  • Added: removePips method;
  • Added: aria support;
  • Added: ariaFormat option (controls aria-valuetext);
  • Fixed: throw a better error when mistakenly trying to initialize noUiSlider with null;
  • Fixed: Made order of events consistent and documented it;
  • Fixed: Border radius of connect bar, white space wrapping of tooltips;
  • Fixed: Slider now uses ownerDocument instead of document;

v9.2.0 (2017-01-11)

  • Added: Version number to exceptions;
  • Added: noUiSlider.version holds current version number;
  • Added: Throw exception on invalid pips configuration
  • Added: Merged pull request that uses less preprocessor to generate CSS;

v9.1.0 (2016-12-11)

  • Fixed: Slider not properly handling multitouch
  • Fixed: Removed a querySelector for the currently active handle
  • Fixed: Removed iOS/webkit flashes on tap
  • Fixed: Incorrect error when using margin/limit with a step smaller than 0
  • Fixed: Drag option using incorrect cursor arrows
  • Added: New padding option
  • Added: Re-introduced .noUi-handle-lower and .noUi-handle-upper classes removed in 9.0.0;
  • Added: Compatibility for legacy connect options removed in 9.0.0

v9.0.0 (2016-09-30)

  • Added: Support for more than 2 handles;
  • Added: format option can be updated;
  • Added: reset method the return slider to start values;
  • Change: connect option is now implemented as a separate node;
  • Change: all event arguments, including the handle number, are now in slider order;
  • Change: updateOptions now modifies the original options object. The reference in slider.noUiSlider.options remains up to date;
  • Change: more events fire when using various behaviour options;
  • Change: on rtl sliders, handles are now visually positioned from the sliders right/bottom edge;
  • Change: events for rtl sliders now fire in the same order has for ltr sliders (with incremental handleNumbers);
  • Change: internal Spectrum component is no longer direction aware;
  • Change: limit and margin must be divisible by step (if set);
  • Removed: .noUi-stacking class. Handles now stack themselves;
  • Removed: .noUi-handle-lower and .noUi-handle-upper classes;
  • Removed: .noUi-background. This is now default;
  • Removed: connect: 'lower' and connect: 'upper'. These settings are replaced by connect: [true, false];
  • Fixed: default tooltip color;
  • Fixed: margin and limit calculated improperly after calling updateOptions with a new range option;
  • Fixed: range option was required in update, even when not updating it;
  • Fixed: Cursor styling is now consistent for disable handles and sliders;
  • Fixed: Sliders now ignore touches when the screen is touched multiple times;

v8.5.1 (2016-04-25)

  • Fix: class mixup in 8.5.0 merge
  • Change: position pips markers relatively
  • Added: ability to completely override the classes used by the slider
  • Fix: removed invalid stopPropagation loop
  • Fix: source properly lints

v8.4.0 (2016-04-17)

  • Fix: don't assume window exists.
  • Fix: :focus style applied to wrong element. 
  • Fix: step option is lost on updating. 
  • Fix: exposed options should be the original options, not the parsed set.
  • Added: handle animation time configurable.
  • Added: slider values can be updated without firing set.
  • Change: internal value calculations no longer limited to 7 decimals. 

v8.3.0 (2016-02-15)

  • Expose several internal features, including options and pips.
  • Add a fifth argument to all events, containing the handle offsets.
  • Fixed margin: 0 throwing an error.
  • Fixed set firing when calling slider.noUiSlider.set with a null value.
  • Fix and clarify some examples

v8.2.0 (2015-11-29)

  • Added 'start', 'end' and 'hover' events
  • Added better tooltip formatting options
  • Bugfixes, including an issues where a mouseup would be missed

v8.0.2 (2015-07-06)

  • Fixed 'unresolved varaible' error.

v8.0.1 (2015-06-30)

  • Fixed an issue with IE11 on touch devices.
  • Removed jQuery dependency! 

v7.0.10 (2014-12-28)

  • Fixed an issue where calling .val(undefined) wouldn't match specification;
  • Values in range are now properly sorted before being used (and can thus be passed in any order);
  • Fixed an error in .noUiSlider('step') where JS floating point precision would mess up a comparison;
  • Fixed the slider styles failing when CSS direction: rtl is set;
  • Fixed throwing an error when running .noUiSlider on an empty selection;
  • Fixed the filter function for the pips plugin not always being called;

v7.0.9 (2014-10-09)

  • Fixed an issue when using the pips plugin with sliders not starting at 0.

v7.0.8 (2014-09-24)

  • Fixed: noUiSlider breaks WordPress menu builder

v7.0.6 (2014-09-12)

  • Added bower support.

v7.0.2 (2014-09-07)

  • Major update.

v7.0.1 (2014-08-23)

  • Major update.

v6.2.0 (2014-05-11)

  • Removed the previously added .classVal and replaced it with a lightweight solution.
  • Fixed a bug in non-linear stepping for RTL sliders.
  • Added checks for min and max in range. 
  • Added the minified version in the source, so it can be managed with Bower. 

v6.1.0 (2014-04-24)

  • Split out value methods into $.classVal. This is included in the release download.
  • $.noUiSlider.Link is now an alias to $.Link. The Link functionality has been moved into a new file. (also in the download).
  • Several bug fixes.
  • Added to and from to number formatting

v6.0.0 (2014-03-17)

  • Added optional non-linear ranges, including stepping.
  • Added new behaviour settings.
  • Added object-oriented serialization.
  • Change events to use jQuery's/Zepto's .on and .off.
  • Removed block event.

v5.0.0 (2013-12-05)

  • Minor rounding fixes
  • Fixed closure

v4.3.0 (2013-11-16)

  • Fixed Zepto problems with jQuery `.is()`
  • Connect for RTL, string fix in IE8, removed test.

v4.2.2 (2013-10-19)

  • Changed implementation of pointerEvents to be compatible with IE11.

v4.2.0 (2013-10-12)

  • added jsLint directive

v4.0.0 (2013-09-23)

  • 4.0 rewrite
  • Fixed setting val by integer

v3.2.1 (2013-03-27)

  • Fixed an issue when initializing a slider with two handles, both on 100%.

v3.2.0 (2013-03-22)

  • Fixed some touch-event related issue

v3.1.1 (2013-03-03)

  • Fixed disabled serialization

v3.0.6 (2013-03-02)

  • Fixed a minor issue in option handling
  • Improved plugin manifest
  • Improved plugin compression

v3.0.0 (2013-03-01)

  • Added responsive design support
  • Added Windows Pointer Events support
  • Fixed issues
  • Reduced file size


This awesome jQuery plugin is developed by leongersen. For more Advanced Usages, please check the demo page or visit the official website.