JSFiddle - React, Tailwind, and code Playground

by levchenko_d

HTML

<div class="_range_slider" slider-direction="horisontal" slider-ft="true" slider-step="1" slider-min="0" slider-max="10">
    <span class="_range_output __low"></span>
    <span class="_range_output __hi"></span>
    <input type="text" name="range_value" value="7,7" />
</div>
<p id="output"></p>

CSS

body {
    min-height: 500px;
}
._range_slider {
    position: relative;
    padding-top: 22px;
    width: 80%;
    margin: 50px;
}
._range_slider input {
    display: none;
}
._range_body, ._range_passed {
    background: #e2e2e2;
    border-radius: 5px;
    width: 100%;
    height: 12px;
    position: absolute;
    top: 5px;
    cursor: pointer;
}
._range_passed {
    width: auto;
    background: #0899E5;
}
._range_control {
    width: 30px;
    height: 22px;
    margin-left: -15px;
    border-radius: 5px;
    background: #ffffff;
    box-shadow: 0 0 2px rgba(0, 0, 0, 0.5);
    position: absolute;
    top: 0;
    cursor: pointer;
}

._range_output{
    display: inline-block;
}

._range_output.__hi{
    float: right;
}

JavaScript

/*
ToDo:

✓ Value output
- touch support
- crossbrowser support
- tooltips
- events
- responsives
- get rid of margin!
- vertical support
- range / slider

*/

var sliders = document.querySelectorAll('._range_slider');

sliders[0].addEventListener('range', function(e){
    console.log(e.value);
})

function inPct(Pixels, pxMax) {
    return (Pixels * (100 / pxMax));
};

for (var i = 0; i < sliders.length; i++) {
    var bodyLine = document.createElement('div'),
        passedLine = document.createElement('div'),
        fromControl = document.createElement('div'),
        toControl = document.createElement('div'),
        outputLo = sliders[i].querySelector('._range_output.__low'),
        outputHi = sliders[i].querySelector('._range_output.__hi'),
        step = sliders[i].attributes['slider-step'].value || 1,
        min = sliders[i].attributes['slider-min'].value || 0,
        max = sliders[i].attributes['slider-max'].value || 100,
        input = sliders[i].querySelector('input'),
        Value = input.value.split(',') || ['' + min, '' + max];

    bodyLine.className = '_range_body';
    fromControl.className = '_range_control _from';
    toControl.className = '_range_control _to';
    passedLine.className = '_range_passed'



    sliders[i].appendChild(bodyLine);
    sliders[i].appendChild(passedLine);
    sliders[i].appendChild(fromControl);
    sliders[i].appendChild(toControl);

    var stp = (parseInt(bodyLine.offsetWidth) / (max - min)) * step;
    
    fromControl.style.left = inPct(parseInt(Value[0]) * stp, parseInt(bodyLine.offsetWidth )) + '%';
    toControl.style.left = inPct(parseInt(Value[1]) * stp, parseInt(bodyLine.offsetWidth ))+ '%';
    passedLine.style.width = inPct((parseInt(Value[1]) * stp) - (parseInt(Value[0]) * stp), parseInt(bodyLine.offsetWidth ))+ '%';  
    
    function setRangeValues(){
        var Low = Math.min(fromControl.offsetLeft+15, toControl.offsetLeft+15),
            Hi = Math.max(fromControl.offsetLeft+15,...