<form>
<label for="range1">One</label>
<input id="range1" type="range" name="range1" min="1" max="10" step="0.1" value="5">
<label for="range2">Two</label>
<input id="range2" type="range" name="range2" min="4" max="32" step="0.5" value="16">
<label for="range3">Three</label>
<input id="range3" type="range" name="range3" min="0" max="100" step="1" value="50">
</form>
* {
border: 0;
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--bg: #e3e4e8;
--fg: #17181c;
--bs1: #ffffff;
--bs2: #c1c2c5;
--tick: #454954;
--transDur: 0.1s;
font-size: calc(20px + (40 - 20)*(100vw - 320px)/(2560 - 320));
}
body, input {
color: var(--fg);
font: 1em/1.5 Muli, sans-serif;
}
body, .range__ticks {
display: flex;
}
body {
background-color: var(--bg);
display: flex;
height: 100vh;
}
form {
margin: auto;
max-width: 15em;
padding: 0 1.5em;
width: 100%;
}
label {
display: block;
font-weight: bold;
}
input[type=range], label {
tap-highlight-color: transparent;
}
input[type=range], .range {
border-radius: 0.75em;
overflow: hidden;
margin-bottom: 1.5em;
}
input[type=range] {
background-color: transparent;
box-shadow:
0.3em 0.3em 0.4em var(--bs2) inset,
-0.3em -0.3em 0.4em var(--bs1) inset;
display: block;
padding: 0 0.1em;
width: 100%;
height: 1.5em;
appearance: none;
appearance: none;
appearance: none;
}
input[type=range]:focus {
outline: transparent;
}
input[type=range]::slider-thumb {
background-color: #255ff4;
border: 0;
border-radius: 50%;
box-shadow:
-0.3em -0.3em 0.5em #0937aa inset,
0 -0.2em 0.2em 0 #0004,
0.3em 0.9em 0.8em #0007;
cursor: pointer;
position: relative;
width: 1.3em;
height: 1.3em;
transition: all var(--transDur) linear;
z-index: 1;
appearance: none;
appearance: none;
}
input[type=range]:focus::slider-thumb {
background-color: #5583f6;
box-shadow:
-0.3em -0.3em 0.5em #0b46da inset,
0 -0.2em 0.2em 0 #0004,
0.3em 0.9em 0.8em #0007;
}
input[type=range]::range-thumb {
background-color: #255ff4;
border: 0;
border-radius: 50%;
box-shadow:
-0.3em -0.3em 0.5em #0937aa inset,
0 -0.2em 0.2em 0 #0004,
0.3em 0.9em 0.8em #0007;
cursor: pointer;
position: relative;
width: 1.3em;
height: 1.3em;
transform: translateZ(1px);
transition: all var(--transDur) linear;
z-index: 1;
appearance: none;
appearance: none;
}
input[type=range]:focus::range-thumb {
background-color: #5583f6;
box-shadow:
-0.3em -0.3em 0.5em #0b46da inset,
0 -0.2em 0.2em 0 #0004,
0.3em 0.9em 0.8em #0007;
}
input[type=range]::focus-outer {
border: 0;
}
.range {
position: relative;
height: 1.5em;
}
.range__ticks {
justify-content: space-between;
align-items: center;
pointer-events: none;
position: absolute;
top: 0;
left: 0.75em;
width: calc(100% - 1.5em);
height: 100%;
}
.range__tick, .range__tick-text {
display: inline-block;
}
.range__tick {
color: var(--tick);
font-size: 0.5em;
text-align: center;
width: 0;
user-select: none;
user-select: none;
user-select: none;
}
.range__tick-text {
transform: translateX(-50%);
}
/* Dark mode */
@media (prefers-color-scheme: dark) {
:root {
--bg: #2e3138;
--fg: #e3e4e8;
--bs1: #3c4049;
--bs2: #202227;
--tick: #c7cad1;
}
}
window.addEventListener("DOMContentLoaded",() => {
let range1 = new NeumorphicRange({
element: "#range1",
tick: 1
}),
range2 = new NeumorphicRange({
element: "#range2",
tick: 4
}),
range3 = new NeumorphicRange({
element:"#range3",
tick: 10
});
});
class NeumorphicRange {
constructor(args) {
this.el = document.querySelector(args.element);
this.min = +this.el.min || 0;
this.max = +this.el.max || 100;
this.step = +this.el.step || 1;
this.tick = args.tick || this.step;
this.addTicks();
}
addTicks() {
// div to contain everything
let wrap = document.createElement("div");
wrap.className = "range";
this.el.parentElement.insertBefore(wrap,this.el);
wrap.appendChild(this.el);
// div to contain the ticks
let ticks = document.createElement("div");
ticks.className = "range__ticks";
wrap.appendChild(ticks);
// draw the ticks
for (let t = this.min; t <= this.max; t += this.tick) {
// zero-width span to allow proper space between each tick
let tick = document.createElement("span");
tick.className = "range__tick";
ticks.appendChild(tick);
let tickText = document.createElement("span");
tickText.className = "range__tick-text";
tick.appendChild(tickText);
tickText.textContent = t;
}
}
}
This Pen doesn't use any external JavaScript resources.