A modern, customizable range slider with tooltip and labels
<div class="range-slider-container">
<div class="range-slider-labels">
<span>0</span>
<span>25</span>
<span>50</span>
<span>75</span>
<span>100</span>
</div>
<div class="range-slider">
<input type="range" min="0" max="100" value="50" class="range-slider-input" id="range-input">
<div class="range-slider-progress"></div>
<div class="range-slider-tooltip">50</div>
</div>
<div class="range-value">Value: <span id="range-value">50</span></div>
</div>
.range-slider-container {
width: 100%;
max-width: 400px;
padding: 20px;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
.range-slider {
position: relative;
height: 40px;
display: flex;
align-items: center;
}
.range-slider-input {
-webkit-appearance: none;
width: 100%;
height: 8px;
background: #e6e6e6;
border-radius: 10px;
outline: none;
z-index: 2;
}
.range-slider-progress {
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
height: 8px;
width: 50%;
background: linear-gradient(90deg, #6a11cb, #2575fc);
border-radius: 10px;
z-index: 1;
pointer-events: none;
}
.range-slider-input::-webkit-slider-thumb {
-webkit-appearance: none;
width: 22px;
height: 22px;
border-radius: 50%;
background: #ffffff;
border: 2px solid #2575fc;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
cursor: pointer;
transition: all 0.2s ease-in-out;
z-index: 3;
}
.range-slider-input::-moz-range-thumb {
width: 22px;
height: 22px;
border-radius: 50%;
background: #ffffff;
border: 2px solid #2575fc;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
cursor: pointer;
transition: all 0.2s ease-in-out;
z-index: 3;
}
.range-slider-input::-webkit-slider-thumb:hover {
transform: scale(1.1);
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}
.range-slider-input::-moz-range-thumb:hover {
transform: scale(1.1);
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}
.range-slider-labels {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
font-size: 12px;
color: #666;
}
.range-slider-tooltip {
position: absolute;
top: -35px;
left: 50%;
transform: translateX(-50%);
background: linear-gradient(135deg, #6a11cb, #2575fc);
color: white;
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
opacity: 0;
transition: opacity 0.2s ease;
pointer-events: none;
}
.range-slider-tooltip::after {
content: '';
position: absolute;
bottom: -5px;
left: 50%;
transform: translateX(-50%);
border-width: 5px 5px 0;
border-style: solid;
border-color: #2575fc transparent transparent;
}
.range-slider-input:hover + .range-slider-progress + .range-slider-tooltip {
opacity: 1;
}
.range-value {
margin-top: 15px;
text-align: center;
font-size: 14px;
font-weight: 500;
}
/* Dark mode styling */
@media (prefers-color-scheme: dark) {
.range-slider-input {
background: #444;
}
.range-slider-input::-webkit-slider-thumb {
background: #222;
border-color: #6a11cb;
}
.range-slider-input::-moz-range-thumb {
background: #222;
border-color: #6a11cb;
}
.range-slider-labels {
color: #aaa;
}
.range-value {
color: #eee;
}
}
document.addEventListener('DOMContentLoaded', function() {
const rangeInput = document.getElementById('range-input');
const rangeValue = document.getElementById('range-value');
const rangeProgress = document.querySelector('.range-slider-progress');
const rangeTooltip = document.querySelector('.range-slider-tooltip');
// Update range slider on input change
function updateRange() {
const value = rangeInput.value;
const percentage = (value - rangeInput.min) / (rangeInput.max - rangeInput.min) * 100;
// Update progress bar width
rangeProgress.style.width = `${percentage}%`;
// Update tooltip value and position
rangeTooltip.textContent = value;
rangeTooltip.style.left = `${percentage}%`;
// Update displayed value
rangeValue.textContent = value;
}
// Set initial state
updateRange();
// Listen for input changes
rangeInput.addEventListener('input', updateRange);
// Show tooltip on hover
rangeInput.addEventListener('mouseenter', function() {
rangeTooltip.style.opacity = '1';
});
rangeInput.addEventListener('mouseleave', function() {
rangeTooltip.style.opacity = '0';
});
});