Customized Range Slider
Question
The native HTML5 control range input has different styles for each browser. In order to achieve a unified style effect, we usually have two solutions to consider, directly modify the CSS style, or simulate a slider control.
Solution One
Modify the css style directly. Use -webkit-slider-thumb
to modify the style of the slider, use -webkit-slider-runnable-track
to modify the style of the track, and then combine events such as :focus
and :hover
to add special effects to make the slider More vivid.
The following describes how to control the style of the input range only through css.
Make a simple demonstration
Or click our Online Demo
Compatibility
We have demonstrated the slider style under webkit
here. If you want to support more browsers, you need to set different pseudo-classes.
::-webkit-slider-thumb
set slider for webkit/blink::-moz-range-thumb
set the slider for Firefox::-ms-thumb
Set slider for IE
There is also the setting of the background bar
::-webkit-slider-runnable-track
set background bar for webkit/blink::-moz-range-track
set the background bar for Firefox::-ms-track
/::-ms-fill-lower
/::-ms-fill-upper
set background bar for IE
Tip
We placed a vertical line in the middle of the slider to indicate the middle position. In addition to using the key shift+\
to type out the vertical line symbol, there are some of the following vertical line symbols that can be used.
丨 | │ | ᅵ | ▎ | ▍ | ▌ |
▋ | ▊ | ▉ | ǀ | ǁ | ׀ |
ا | ། | ༎ | ᅵ | ‖ | ∣ |
∥ | ⑊ | │ | ┃ | ║ | ╵ |
╷ | ╹ | ╻ | ▅ | ▆ | ▇ |
█ | ▐ | ▕ | ◫ | ▥ | ▯ |
▮ | ❘ | ❙ | ❚ | 〡 | 〢 |
| | ﺍ | ︳ | ︲ | ︱ | ﺍ |
〣 | ㅣ | ㆐ | 丨 |
Solution Two
Simulates a slider control. For example, use the div
element to simulate the range input style, and use pointdown
, pointmove
, pointup
and other events to simulate the behavior of input
code show as below
<div id="container">
<div id="slider" class="slider">
<div class="thumb"></div>
</div>
<div class="rate">50%</div>
</div>
Organize the style
#container {
margin: 30% auto;
width: 300px;
text-align: center;
}
.slider {
border-radius: 6px;
background: #e0e0e0;
height: 10px;
}
.thumb {
touch-action: none;
width: 20px;
height: 20px;
border-radius: 20px;
position: relative;
left: 140px;
top: -5px;
background: gray;
cursor: pointer;
transition: transform 0.3s;
}
.rate {
margin-top: 20px;
}
write event
let thumb = slider.querySelector(".thumb");
let rate = container.querySelector(".rate");
let shiftX;
const total = slider.offsetWidth - thumb.offsetWidth;
function onThumbDown(event) {
event.preventDefault(); // prevent selection start (browser action)
shiftX = event.clientX - thumb.getBoundingClientRect().left;
thumb.setPointerCapture(event.pointerId);
thumb.style.transform = "scale(1)";
thumb.onpointermove = onThumbMove;
thumb.onpointerup = (event) => {
// dragging finished, no need to track pointer any more
// ...any other "drag end" logic here...
thumb.onpointermove = null;
thumb.onpointerup = null;
thumb.style.transform = "scale(1.2)";
};
}
function onThumbMove(event) {
let newLeft = event.clientX - shiftX - slider.getBoundingClientRect().left;
// if the pointer is out of slider => adjust left to be within the boundaries
if (newLeft < 0) {
newLeft = 0;
}
let rightEdge = slider.offsetWidth - thumb.offsetWidth;
if (newLeft > rightEdge) {
newLeft = rightEdge;
}
thumb.style.left = newLeft + "px";
setRate(newLeft);
}
function onThumbEnter(event) {
thumb.style.transform = "scale(1.2)";
}
function onThumbLeave(event) {
thumb.style.transform = "scale(1)";
}
function setRate(left) {
rate.innerText = ((left / total) * 100).toFixed(0) + "%";
}
thumb.onpointerdown = onThumbDown;
thumb.onpointerenter = onThumbEnter;
thumb.onpointerleave = onThumbLeave;
thumb.ondragstart = () => false;
see the actual effect
Reference
For more detailed interpretation, please refer to the following blog post
Comments