To implement the triangle right below your slider, you can add the following CSS code using a before pseudo selector:
input[type="range"]+label::before {
content: "";
clip-path: polygon(0 0, 50% 100%, 100% 0);
width: 21px;
height: 20px;
background: white;
display: block;
position: absolute;
top: 29px;
left: -0.5px;
border-top-right-radius: 2px;
border-top-left-radius: 2px;
}
Modify the CSS selector with the following styles:
input[type="range"]+label {
background-color: #fff;
position: absolute;
top: -35px;
left: 140px;
width: 20px;
height: 30px;
padding: 5px 0;
text-align: center;
border-radius: 4px;
border-bottom-right-radius: 0px;
border-bottom-left-radius: 0px;
font-size: 10px;
}
Update this line in your JavaScript code changing from 10, -10 to 0, 0:
const left =
value * (numWidth / max) -
numLabelWidth / 2 +
scale(value, min, max, 0, 0);
Here is a functional snippet for reference:
const range = document.getElementById("range");
// Mapping a range of numbers to another range
const scale = (num, in_min, in_max, out_min, out_max) => {
return ((num - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min;
};
range.addEventListener("input", (e) => {
const value = +e.target.value;
const label = e.target.nextElementSibling;
const rangeWidth = getComputedStyle(e.target).getPropertyValue("width");
const labelWidth = getComputedStyle(label).getPropertyValue("width");
// Remove pixels
const numWidth = +rangeWidth.substring(0, rangeWidth.length - 2);
const numLabelWidth = +labelWidth.substring(0, labelWidth.length - 2);
const max = +e.target.max;
const min = +e.target.min;
const left =
value * (numWidth / max) -
numLabelWidth / 2 +
scale(value, min, max, 0, 0);
label.style.left = `${left}px`;
label.innerHTML = value;
});
...