Кривое отображение текущего значения range slider-а

Рейтинг: 0Ответов: 2Опубликовано: 30.06.2023

Всем привет. Сделал 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>

Ответы

▲ 1Принят

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>

▲ 1

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>