Customizable slider (range) component (widget) for JavaScript with no external dependencies (even jQuery!)
Enhance your users' experience with an attractive and interactive way to input numbers.
- No dependencies!
- Totally responsive!
- Positive and negative integers supported
- Neat design: plain 2D or stylish 3D view, smooth fade animations
- 3 pre-defined themes and possibility to customize your own theme
- 3 pre-defined sizes
- 3 shapes of the handle: square, round or rectangle
- Popup showing current value when moving
- Control over min, max and current value labels visibility and placement
- Full control over the value: min-max bounds, integer step, unit of measurement, possibility to prevent from dragging to a particular number under some circumstances
- Simple API to interact with the value
- OOP-style (
RangeSlider
class with settings hash in constructor) - Source code in 3 samples: ES 2015, ES 5.1 and ES 5.1 minified
Tested in:
- Chrome 56
- Firefox 51
- IE 10
IE 9 is semi-supported: slider functions well but 3D design looks strange there.
Should also work in all major browsers, but need to test. If you find it working in lower versions of Chrome or FF, or in other browsers, please communicate to update the doc!
Download the repo folder and open index.html
in your browser.
It uses some self-explaining examples to demonstrate widget's abilities.
An example of default initialization:
<div id="slider"></div>
<script>
new RangeSlider(document.getElementById("slider"));
</script>
OR
var slider = new RangeSlider();
document.body.appendChild(slider.getElement());
Example of maximal configuration:
// skip the first parameter if you want to create new element and attach it later
new RangeSlider(element, {
step: 10,
min: 80,
max: 1000,
value: 200,
unit: "km/h",
width: "75%",
design: "3d",
showMinMaxLabels: true,
showCurrentValueLabel: true,
labelsPosition: "bottom",
popup: "bottom",
theme: "attention",
handle: "round",
size: "large"
});
npm install range-slider
Then in your JS code:
require("range-slider")
This will require minified file as a dependency.
It's assumed to work with both CommonJS or AMD, but needs to be tested. Please communicate if you confirm.
Don't forget to add CSS file manually!
Download one of the versions from src directory (either EcmaScript 6 full, EcmaScript 5 full or EcmaScript 5 minified). Attach the script anywhere on your page.
Download full or minified CSS and attach to your page.
For example:
<head>
<link rel="stylesheet" href="css/range-slider.min.css">
</head>
<body>
<div id="slider"></div>
<script src="vendor/range-slider.min.js"></script>
<script>
new RangeSlider(document.getElementById("slider"), {
min: 0,
max: 10000,
value: 1000,
step: 50
});
</script>
</body>
If you want to contribute or research the repo, clone it and run npm install
.
Then run npm run build
each time you want to compile and minify ES6 and CSS source code.
Type: number|string
Default: 0
Initial value. If it's not integer it gets rounded. If it's outside of min-max boundary, it is set to the closest allowed value.
String value is transformed to number when possible, otherwise default value is used. The same is true for all numeric settings.
Type: number|string
Default: 0
Minimal allowed value.
Type: number|string
Default: 100
Maximal allowed value.
Type: number|string
Default: 1
Step by which value gets changed when moving slider.
It is counted from the initial value, so min/max values cannot be reached in case they differ from initial value not by integer amount of steps (e.g. min 1, max 5, initial value 2, step 2).
Type: string
Default: null
Unit of measurement (mm, ll, inch, km/h, %, etc). Displayed in labels and popup.
Type: number|string
Default: null
When not specified, default width of the element is used. So e.g. block element gets stretched by 100%.
When string is specified, it's used as a width
css property (so all css units are supported).
When number is specified, it's transformed to a string by appending "px".
Type: <"2d", "3d">
Default: "3d"
General design of the slider: plain 2D or neat 3D (see example).
Note that lower case is required for all string settings
Type: <"default", "positive", "attention", string>
Default: "default"
Color scheme of the slider.
If custom string is specified, you can customize your own theme
(see Making your custom theme section below). In this case class name is added to
the slider element containing specified string: rs-theme-${theme}
.
Type: <"small", "medium", "large">
Default: "medium"
Size of the slider. It is not related to the width of the component (see width
property for this).
It defines height of the bar, size of the handler, font-size of labels, etc. Custom values are not supported here.
Type: <"square", "round", "rect">
Default: "square"
Shape of the handler of the slider.
Type: <"top", "bottom", null>
Default: "top"
Defines position of the popup displayed when user is moving handler. You can change colors of the popup with your custom CSS (see changing popup color section below).
Use null
(or any falsy value) to disable popup.
Type: boolean
Default: true
Whether to display min and max labels or not.
You can change labels styling with your custom CSS rules. See more in changing labels style section.
Type: boolean
Default: false
Whether to display current (actual) value label.
It is displayed near the handler and moves together with it. If you want to hide it during movement and display only statically (i.e. only when user is not interacting with the slider), see hiding current value label during interaction section below.
When popup
is enabled, current value label is hidden automatically during the movement.
Type: <"top", "bottom">
Default: "top"
Defines position of max, min and current value labels.
All callbacks are invoked with a context of the slider instance. So you can invoke its methods
inside of callbacks (e.g. this.getValue()
, this.setValue(x)
).
Called when user begins interacting with the slider. Single argument contains current value.
Return false
to prevent interaction.
Called when user ends interacting with the slider. Single argument contains new value.
Called when user moves handler and the value gets changed (not called on each cursor movement). Single argument contains new value.
Return false
to prevent the new value from being set (handler is not moved in that case).
This way you can exclude custom values from being set or handler to be moved under your custom
conditions.
There are several public methods that can be called on the instance of slider (returned when calling
new RangeSlider(...)
). All other methods you find in code are private and should not be called
from outside as it might break component functionality (or compatibility with future versions).
There are also several public static methods of RangeSlider
class, but they are not really useful
and hence not described here. You can learn more from code.
Get current value.
Set value of the slider.
If it's not integer or is outside of max/min bounds, it gets rounded to the closest allowed value.
Get DOM element of the slider.
Set width of the slider.
Number is transformed to string by adding "px". String represents CSS width of the slider element.
Get value suffixed with the unit of measure.
If value parameter is not specified, current value is used.
It is possible to customize slider parts' colors and visibility with your own CSS rules. Sizes are also possible to customize, but it's much harder as they involve many dependencies in css rules.
Here are described some useful cases. For everything else feel free to modify or override existing CSS rules.
All class names of the component parts are prefixed with "rs-" to avoid conflicts with other rules in your project.
It is possible to specify your own theme name in the slider settings, e.g:
new RangeSlider({
theme: "custom"
});
In this case class name will be added to the slider element formed as rs-theme-${theme}
("rs-theme-custom" for the example specified above).
You can customize your theme then with the following CSS (assumed theme is set to "custom"):
.rs-theme-custom .rs-progress,
.rs-theme-custom .rs-progress::before {
background: pink;
}
.rs-theme-custom .rs-handle {
background: deeppink;
}
.rs-theme-custom.rs-design-3d .rs-progress,
.rs-theme-custom.rs-design-3d .rs-progress::before {
background: red;
}
The first rule is used to set general progress-bar color.
The second rule is used to set handler color in both 2D and 3D modes (you can differentiate
between the modes by adding .rs-desing-2d
or .rs-design-3d
class to the outer selector).
The third rule is used to adjust progress-bar color in 3D mode.
To change color of the popup use the following selectors:
.range-slider .rs-popup {
background: black;
color: white;
}
.range-slider .rs-popup-top::after {
border-top-color: black; /* same as background above! */
}
.range-slider .rs-popup-bottom::after {
border-bottom-color: black; /* same as background above! */
}
The last 2 rules are needed to also customize small triangle of the popup.
Make sure your rules have higher priority than default! I.e. they are included after component's stylesheet,
or they use your custom theme selector like .range-slider.rs-theme-custom
instead of simple .range-slider
.
To change labels color or font use selector .rs-labels
.
To change particular label use one of .rs-labels .rs-label-left
, .rs-labels .rs-label-right
or
.rs-labels .rs-label-middle
selectors.
Make sure your rules have higher priority than default! I.e. they are included after component's stylesheet,
or they use your custom theme selector like .range-slider.rs-theme-custom
before .rs-labels
.
In general, to adjust slider styling during interaction, use .range-slider.rs-active
outer selector.
If you want to see current value label, but to hide it when user is moving the slider, and if you don't use popup, you can add the following CSS rule:
.range-slider.rs-active .rs-label-middle {
display: none;
}
If you want to enable fading animation for current value label when it's hiding and showing, use
opacity: 0
instead of display: none
. But in this case it will blink when value is changed instantly
by clicking on progress bar rather than by moving the handler.
- add more public methods to control the component dynamically
- validate all settings and prevent from XSS
- add ability for selecting range of values?
Alexey Grinko, 2017 (c)