UPDATE NOTICE
This version of Slider89 hasn't been maintained for a while and is not all that good either, so please refrain from using it. Don't use these docs for any reason other than to admire their weird-but-beautiful-nes.
Slider89 has been rewritten completely from scratch and a new version of Slider89 is well underway. With it, these docs will be overhauled. You can follow the development on its GitHub page.
#Introduction
If you have at some point needed an input type=range while developing a website you'll know that they are awesome. They fit with a lot of use cases and are very convenient to both interact with as user and deal with as developer.
However, the restriction of not being able to style it very well is a point which isn't easy to ignore. People tell me that there are many ways to style a range input, to which I answer with the question whether approximately 80 lines of css (cross-browser support included) solely for one range input is worth it.
This is why I made a library to solve this very problem: Slider89, which also happened to solve a lot more problems. How convenient!
#What is this?
Slider89 is a very simple library for easily creating sliders (range inputs) for a webpage. Being based on custom HTML elements and Javascript instead of a built-in browser side <input>-element, it allows for full styling and behaviour customization. It is, for example, very useful for modifying values on the go.
A basic slider can look like this (Its background-color is a bit darker but otherwise this is an all-default slider):
Obviously, the default theme and configuration will not fit into everyone's design and use cases, but Slider89 is strong when it comes to customization. Beware, however, that it is still in an early alpha state and more features are yet to come.
Please also note that while Slider89 is in the alpha state, everything may change without further warnings, including exposed getter/setter properties and functions.
#Getting started
Slider89 is a client-side library (I don't know yet how useful it is to have it on NPM), so you first need to fetch the necessary files and load them up into your HTML document.
There are two ways of doing this: you can either download them from its repository on GitHub, https://github.com/Hallo89/Slider89, or fetch the files from the repo's website as seen below to always get the latest available version.
In both cases only two files are needed: slider89.js
and slider89.css
.
You'll then need to link them in your HTML file (first the download way):
<script src="yourpath/slider89.js"></script>
<link rel="stylesheet" href="yourpath/slider89.css">
or, fetching from the website:
<script src="https://hallo89.github.io/Slider89/slider89.js"></script>
<link rel="stylesheet" href="https://hallo89.github.io/Slider89/slider89.css">
Tip: I prefer to load both script and style at the end of the document (before the closing body tag) so that the page will build a tiny bit faster. That's because one will most likely not need the files before as the DOM needs to build up before one can interact with it, which makes sense.
Now that everything is loaded up, we can start to create sliderz. All you have to know is the initialization method; everything else can be taken from the documentation section.
To create one instance of a slider, we do the following in our Javascript:
const mySlider = new Slider89(targetElement);
We create a new instance of the Slider89
class with the new
operator and pass the DOM element we want the slider to be created in as argument into the function.
Assigning the instance to a variable is optional, it will be created in the given element one way or another, but without a variable one obviously can't do anything with the slider.
An all-default slider initialized plainly like this will look like the example you see above:
As stated above, config options are available: to configure the slider, we pass an additional argument into the Slider89 constructor, an object which we equip with configuration properties. Here's an example:
const mySlider = new Slider89(targetElement, {
min: -50,
max: 175,
value: 80
});
Which would turn out into this:
#Documentation
This chapter will introduce all available methods, variables etc. with a thorough explanation.
Version selector
If you are restricted to a specific version, choose it here and the docs will adapt.
- New property:
structure
. It takes a string similar to an XML structure to assemble a customized HTML structure element
has been changed in favor of the new structure system: It is now a JavaScript object containing every part of the slider as opposed to only the root elementtipDuration
can now be set tofalse
to prevent it from disappearing altogether- The HTML classing has been changed to improve stylability: non crucial CSS suited for altering, has been moved into a new, independent class to be spoken to without nesting in the selector,
slider89_{slider-part}
; crucial CSS is still selected with a (more difficult to override).slider89 .slider_{slider-part}
- New property:
taskMouseUp
, taking a function to be executed every time the mouse is released after engaging with a slider possessing this property value
is now trimmed to the value ofcomma
, when specified, within the same initialization- If
value
is changed to more thanmax
or less thanmin
withnewValues()
, they are now set to min and max accordingly - Fixed the width not computing anew when changing values with
newValues()
- Fixed new
min
,max
andcomma
values being ignored when they are changed to 0 innewValues()
Slider89's initial release - more updates will come in the future.
#Properties
These are the key to reading values from the slider and defining its properties.
Every property's value is read using <sliderInstance>.<property>
# Configuration properties
Define the slider's configuration as properties of an object passed as a parameter into various functions.
-
min
- The minimum value of the slider's range
-
├
type:
number
-
├
influencing:
width at 'auto'
-
└
default:
0
-
max
- The maximum value of the slider's range
-
├
type:
number
-
├
influencing:
width at 'auto'
-
└
default:
100
-
width
-
The final width of the slider.
A number represents the width in pixels regardless of the slider's range, whereas the keyword 'auto' computes the width automatically from the slider's range in a 1:1 ratio.
If the propertyabsWidth
is false (default), the width is implicit; it is expanded by a small amount resembling the left/right padding of the slider (Currently half the thumb's width either side, configurable in the future) in order to get an expected result -
├
type:
number
-
├
unit:
px
-
├
available keywords:
'auto'
-
├
influences:
absWidth
,min
,max
-
└
default:
'auto'
-
classList
- An array containing CSS classes to be added to the slider's top-level element in its HTML structure
-
├
type:
array<string>
-
├
influencing:
HTML structure
-
└
default:
[]
-
task
- This property takes a reference to a function to be executed every time the slider is moved (event: mousemove). A function reference is either an anonymous function or a declared function without parentheses
-
├
type:
function reference
-
└
default:
undefined
-
taskMouseUp
-
This property behaves similarly to
task
but it is only executed every time the mouse button is released after the slider has been interacted with (event: mouseup) -
├
type:
function reference
-
└
default:
undefined
-
structure
-
An XML-like format resulting in the final HTML structure of the slider.
(For now) necessary tags:<wrapper>
,<knob>
,<tooltip>
,<caption>
, where every tag exceptwrapper
is a non-closing one-line tag.
Definition of attributes: inside a tag,[!]attributeName(value1[, value2[, ...]])
, where an exclamation mark in front of the attribute overwrites potential library-side pre-defined values.
Custom elements can be inserted anywhere. They need to have a unique name and their tag type (div, etc.) can be declared after their name.
Inner text content is created by simply placing it inside the tag at the end in quotation marks.
Example:<caption !class(input_header)> <text span class(char_info, default) "Text appearing inside the element"> <wrapper class(input)> <knob style(height: 50px)> <tooltip> </wrapper>
-
├
type:
string
-
├
influencing:
HTML structure
-
└
default:
'<wrapper><knob><tooltip></wrapper><caption>'
-
absWidth
- 'Absolute width'; setting this to true computes the slider's width explicitly without taking the slider's (left/right) padding (For now only the default padding is valid) into account
-
├
type:
boolean
-
├
influencing:
width
-
└
default:
false
-
trimComma
-
If true, the value's decimal places are culled if they are 0. This is an aesthetic property coming handy at the value-displaying tooltip.
Example: 6.000 is trimmed to 6 -
├
type:
boolean
-
└
default:
true
-
tipDuration
-
The number of milliseconds after which the value tooltip should vanish when the slider has stopped being interacted with.
Setting it tofalse
disables the timer, making the value never disappear -
├
type:
number
ORfalse
-
├
unit:
ms
-
└
default:
250
- The number of milliseconds after which the value tooltip should vanish when the slider has stopped being interacted with
-
├
type:
number
-
├
unit:
ms
-
└
default:
250
-
replaceNode
-
If set to true, the slider instance will replace the
targetNode
on initialization instead of being appended inside it - ├ WRITE ONLY
-
├
type:
boolean
-
├
influencing:
Slider89
-
└
default:
false
# Read only
The following properties are read only and may not be used as configuration properties
-
element
- An object containing all nodes of the final HTML structure after the slider instance's initialization
- ├ READ ONLY
-
├
type:
object<HTMLnodes>
-
├
influences:
buildElement
-
└
default:
undefined
- The top-level HTML element (see HTML structure) of the final slider instance after initialization
- ├ READ ONLY
-
├
type:
HTMLnode
-
├
influences:
buildElement
-
└
default:
undefined
# Internal
Below listed are properties which are internal to Slider89 and serve no purpose for the user but maybe you want to hack the library idk but feel free to
-
taskLock
-
If a task is specified: while dragging the slider, if the previous and new value are equal to each other, the
task
is executed once andtaskLock
is set to true which prevents further executions oftask
if the value has still not changed. If the value has changed again,taskLock
is set to false - ├ INTERNAL
-
├
type:
boolean
-
├
influences:
executeSlider
,task
,taskMouseUp
-
└
default:
false
-
tipTimer
-
The current
Timeout
instance of the value tooltip timer (see tipDuration) which is terminated when the slider is dragged anew while a previous timeout instance was still running - ├ INTERNAL
-
├
type:
Timeout
-
├
influences:
executeSlider
,tipDuration
-
└
default:
undefined
#Methods (functions)
# Constructor
-
sliderInstance = Slider89(
targetNode[, configProperties]) -
The
Slider89
class and its constructor; initialize a slider instance by using thenew
keyword in front of it and binding it to a variable.
Example:A more advanced example with a configured slider:const mySlider = new Slider89(someElement);
const mySlider = new Slider89(someElement, { max: 400, value: 300, replaceNode: true });
-
├
Definitions:│
targetNode
= DOM node: Creation target of the slider instance -
└
influences:
replaceNode
# Instance functions
Functions under this category are called on a slider instance
-
sliderInstance.newValues(
configProperties) -
This function restructures the slider it was called on with configuration properties given as a parameter.
Although properties could be overriden usingsliderInstance.configProperty = newValue
, this function ensures every dependent and dependency is restructured as well. For example, it writes a new caption into the element, it sets a new width of the element, etc.
Additionally, ifmin
ormax
is changed, thevalue
recomputes itself based on the previous min-max-ratio
In the future, I may find a way to deprecate this function -
├
Definitions:
-
└
influences:
Configuration properties
#
The slider89
object
'slider89
' (take notice that it's a lowercase "s"!) is a standalone object used for functions which are called without a reference to a slider instance
-
slider89.defaultValues(
configProperties) - Called before a slider is created, it sets default configuration properties implicitly applied to every afterwards created slider instance
-
├
Definitions:│
slider89
= A standalone object storing global values
# Internal
As with the internal properties, these values serve no purpose for the user but are listed here to give the user (and hacker) full transparency
-
element = sliderInstance.buildElement(
targetNode, replaceNode) -
Builds the slider's HTML structure into the specified
targetNode
, adding additional classes from theclassList
property, if present. IfreplaceNode
is true, it replacestargetNode
(acquired fromSlider89
).
The object containing all HTML elements of the final HTML structure (acquired fromparseHTML
) is returned to be written intoelement
- ├ INTERNAL
-
├
Definitions:
-
├
influences:
replaceNode
,parseHTML
,classList
-
└
influencing:
HTML structure
,element
-
Builds the slider's HTML structure into the specified
targetNode
, adding additional classes from theclassList
property, if present. IfreplaceNode
is true, it replacestargetNode
.
The function returns the created element to be written into a variable (->element
) - ├ INTERNAL
-
├
Definitions:
-
├
influences:
replaceNode
,classList
-
└
influencing:
HTML structure
,element
-
sliderInstance.executeSlider(
clickedCoordinate) -
This function is executed every time the
mousemove
event, and more specifically themouseMove
function, is fired and handles the value, tooltip, specifiedtask
/taskMouseUp
function, etc. - ├ INTERNAL
-
├
Definitions:│
clickedCoordinate
= int: A screen-related x-coordinate where the mouse has been clicked -
├
influences:
element
,task
-
└
influencing:
value
,tipTimer
,taskLock
-
result = sliderInstance.checkTask(
task) -
A function evaluating whether a handed-over
task
is valid:
If it is, plainly return it without doing anything, if not, for example because it has been declared with parentheses (which Javascript cannot explicitly check), throw an error into the console and returnfalse
- ├ INTERNAL
-
├
Predecessor:
setTask
-
├
Definitions:│
result
= The passed task if the evaluation was successful orfalse
-
└
influencing:
task
,taskMouseUp
-
sliderInstance.setTask(
target, task) -
A function evaluating whether a handed-over
task
is valid. If it is, write it into the specifiedtarget
which is an object with the Slider89 infrastructure, so eitherSlider89
or theslider89 object
If the task is no valid function, for example declared with parentheses, throw an error into the console - ├ INTERNAL
-
├
Successor:
checkTask
-
├
Definitions:│
target
= The object to write into; either the slider instance (see constructor) or theslider89 object
-
└
influencing:
task
-
finalWidth = sliderInstance.computeWidth(
,width) finalWidth = sliderInstance.computeWidth(
valueObject) -
If
width
is'auto'
, compute the width automatically based onmin
andmax
, if it isn't, only takeabsWidth
into account - ├ INTERNAL
-
├
Definitions:│
finalWidth
= int: The final computed width of the passed width│width
= int: The width to be computed -
├
influences:
min
,max
,absWidth
-
└
influencing:
width
-
htmlNodes = sliderInstance.parseHTML(
structure) -
This function will parse a given
structure
into valid HTML, taking every attribute, inner text content etc. into account.
It will return every created HTML node in an object, with the in the structure specified tag name as object name - ├ INTERNAL
-
├
Definitions:
-
├
influences:
structure
-
└
influencing:
buildElement
,HTML structure
-
sliderInstance.mouseMove(
event) -
Is executed by the mousemove event, being its own function for the ability to remove the event listener afterwards, and executing
executeSlider
, passing the parameter of the event. - ├ INTERNAL
-
├
Definitions:│
event
= The event parameter handed over by the event listener
checkTask
#HTML & CSS structure
As of version 0.2.0
(with the introduction of the structure system), CSS has been split into two sections: crucial and non-crucial. Crucial CSS is declared with a strict .slider89 .slider_{sliderPart}
, whereas uncrucial styles are matched with the new class .slider89_{sliderPart}
. This ensures a good ability to style the slider without the user having to nest their selectors to overcome the strict selectors.
-
HTML structure
-
<div class="slider89 [{additional classes}]"> <div class="slider slider89_wrapper" style="width: {width}px"> <div class="slider_knob slider89_knob" style="transform: translateX({value}px)"></div> <div class="slider_tooltip slider89_tooltip right hidden noselect">{value}</div> </div> <div class="slider_header slider89_header">{caption}</div> </div>
-
<div class="slider89 [{additional classes}]"> <div class="slider" style="width: {width}px"> <span class="slider_knob" style="transform: translateX({value}px)"></span> <span class="slider_tooltip right hidden noselect">{value}</span> </div> <span class="slider_header">{caption}</span> </div>
-
CSS structure
-
.slider89 { display: inline-block; } .slider89 .slider { position: relative; font-family: monospace; font-size: 18px; font-weight: bold; padding: 0; } .slider89_wrapper { background-color: hsl(0, 0%, 19%); height: 25px; } .slider89 .slider_knob { position: absolute; cursor: pointer; left: 0; z-index: 1; } .slider89_knob { height: 25px; width: 14px; background-color: hsl(0, 0%, 27%); } .slider89 .slider_tooltip { position: absolute; display: flex; align-items: center; height: 100%; cursor: default; opacity: 1; transition: .2s ease-out; } .slider89_tooltip { color: hsl(0, 0%, 45%); padding: 1px 3px 0; } .slider89 .slider_tooltip.left { left: 0; } .slider89 .slider_tooltip.right { right: 0; } .slider89 .slider_tooltip.hidden { opacity: 0; } .slider89_header { color: hsl(0, 0%, 70%); font-family: 'Calibri', serif; font-size: 20px; } .noselect { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }
-
.slider89 { display: inline-block; } .slider89 .slider { position: relative; padding: 0; background-color: hsl(0, 0%, 19%); font-family: monospace; font-size: 18px; font-weight: bold; height: 25px; } .slider89 .slider_knob { position: absolute; cursor: pointer; left: 0; height: 25px; width: 14px; background-color: hsl(0, 0%, 27%); z-index: 1; } .slider89 .slider_tooltip { position: absolute; display: flex; align-items: center; padding: 1px 3px 0; color: hsl(0, 0%, 45%); height: 100%; cursor: default; opacity: 1; transition: .2s ease-out; } .slider89 .slider_tooltip.left { left: 0; } .slider89 .slider_tooltip.right { right: 0; } .slider89 .slider_tooltip.hidden { opacity: 0; } .slider89 .slider_header { color: hsl(0, 0%, 70%); font-family: 'Calibri', serif; font-size: 20px; display: block; } .noselect { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }