Кривое отображение текущего значения range slider-а
Всем привет. Сделал range-slider, и написал код для отображения текущего значения под ползунком. Проблема в том, что блок с текущим значением отображется со смещением. Мне нужно отображение по центру.
const rangeSlider = document.querySelector('.range__slider'),
rangeValue = document.querySelector('.range__value_current');
rangeSlider.addEventListener('input', (e) => {
let value = e.target.value,
max = e.target.max;
rangeValue.style.left = (rangeSlider.offsetWidth / max) * value + 'px';
rangeValue.innerText = value;
});
.range {
background-color: grey;
padding: 40px 0;
}
.range__inner {
position: relative;
padding-bottom: 25px;
width: 100%;
}
.range__value {
position: absolute;
font-size: 12px;
line-height: 14px;
bottom: 0;
}
.range__value_current {
background-color: red;
left: 0;
}
.range__value_min {
left: 0;
}
.range__value_max {
right: 0;
}
.range__slider {
-webkit-appearance: none;
height: 1px;
width: 100%;
background-color: #B6D7E8;
outline: none;
border: none;
}
.range__slider::-webkit-slider-thumb {
-webkit-appearance: none;
width: 10px;
height: 10px;
border-radius: 50%;
background: #fff;
cursor: pointer;
}
<div class="range">
<div class="range__inner">
<div class="range__value range__value_current">0</div>
<div class="range__value range__value_min">0</div>
<input class="range__slider" type="range" min="0" max="160" value="0">
<div class="range__value range__value_max">160</div>
</div>
</div>
Ответы (2 шт):
Автор решения: Qwertiy
→ Ссылка
const rangeSlider = document.querySelector('.range__slider'),
rangeValue = document.querySelector('.range__value_current');
rangeSlider.addEventListener('input', (e) => {
let value = e.target.value, max = e.target.max;
rangeValue.style.left = `calc(7px + (100% - 14px) * ${value / max})`;
rangeValue.textContent = value;
});
.range {
background-color: grey;
padding: 40px 0;
}
.range__inner {
position: relative;
padding-bottom: 25px;
}
.range__value {
position: absolute;
bottom: 0;
width: 4ch;
margin: 0 -2ch;
text-align: center;
font-size: 12px;
line-height: 14px;
}
.range__value_current {
left: 7px;
}
.range__value_min {
left: 7px;
}
.range__value_max {
right: 7px;
}
.range__slider {
-webkit-appearance: none;
margin: 2px;
height: 1px;
width: calc(100% - 4px);
background-color: #B6D7E8;
outline: none;
border: none;
}
.range__slider::-webkit-slider-thumb {
-webkit-appearance: none;
width: 10px;
height: 10px;
border-radius: 50%;
background: #fff;
cursor: pointer;
}
<div class="range">
<div class="range__inner">
<div class="range__value range__value_current">0</div>
<div class="range__value range__value_min">0</div>
<input class="range__slider" type="range" min="0" max="160" value="0">
<div class="range__value range__value_max">160</div>
</div>
</div>
Автор решения: Qwertiy
→ Ссылка
document.querySelector('.range__slider').addEventListener('input', e => {
const { value, min, max } = e.target
const range = e.target.closest('.range')
range.style.setProperty('--part', (value - min) / max)
range.querySelector('.range__value_current').textContent = value
})
.range {
display: grid;
--part: 0;
grid-template: "r r r r r" "min . cur . max" / 0 calc(var(--part) * 100%) 0 1fr 0;
gap: .5em 0;
padding: 40px 7px;
background-color: grey;
}
.range__value {
width: 4ch;
margin: 0 -2ch;
text-align: center;
font-size: 12px;
line-height: 14px;
}
.range__value_current {
grid-area: cur;
}
.range__value_min {
grid-area: min;
}
.range__value_max {
grid-area: max;
}
.range__slider {
grid-area: r;
-webkit-appearance: none;
margin: -5px;
height: 1px;
background-color: #B6D7E8;
outline: none;
border: none;
}
.range__slider::-webkit-slider-thumb {
-webkit-appearance: none;
width: 10px;
height: 10px;
border-radius: 50%;
background: #fff;
cursor: pointer;
}
<div class="range">
<input class="range__slider" type="range" min="0" max="160" value="0">
<div class="range__value range__value_min">0</div>
<div class="range__value range__value_current">0</div>
<div class="range__value range__value_max">160</div>
</div>