◆ multirange がメンテされてない
  ◆ Chrome 83 の問題がそのまま
  ◆ この機能が polyfill でなくなって作者のやる気もなさそう
◆ とりあえずの対応したけど メンテされないなら自作しよう

multirange

input の type="range" を使うとレンジバーが表示されて スクロールバーのようにマウスで掴んで動かして範囲内の値を選択できます
0 から 100 から 1 つ選ぶみたいなときは便利なのですが 範囲を選びたいときにはデフォルトのものでは使えません
multirange というライブラリを使えばマウスでつかめる箇所が 2 つになって範囲選択ができるようになります

今回これを使おうとしたのですが…… Chrome 83 の仕様変更の対応がまだされてませんでした
Chrome 83 では input 系の見た目が一新されてレンジバーでは選択してる部分より左側には色がつくようになりました
そのせいで multirange もわかりづらくこうなってしまいます

multirange

Github を見ても issue はできてるもののコメントは一切なく 全体の最終コミットも半年ほど前です
それに元々 multi range は標準機能の予定がありこのライブラリは Polyfill だったそうですが 今では標準機能から除外されて Polyfill ではなくなっています
そのこともあり 作者の人がメンテに興味がないみたいな書き込みもしています
修正される期待はあまりできない状況です

CSS 対応

色がついた部分を透明にできれば元通り使えるかなと CSS を色々いじってみたのですが webkit プレフィックスがつくようなブラウザ独自のスタイルで調整するもので 今のところは Chrome83 から色がついたところだけを調整することはできなそうでした

-webkit-appearance を none にすると色は消えるのですがスライド可能なエリア全体が非表示になります
色がつく左側もつかない右側も非表示で 動かすことのできる●だけが残ります
この状態にスライド可能なエリアを表示だけできればいいかなと 背景色を使って選択してないエリアを表現すれば一応それらしくはなりました

この CSS を追加します

.multirange {
background: #e0e0e0;
height: 6px;
-webkit-appearance: none;
}

multirange-fixed

自作版

一応これで完了だったのですが なんか WebComponent にしたいなぁ とかメンテされなさそうなのを今から使うのもなぁ という気持ちがあります
機能的にはたいしたことしてないので 一から WebComponent で自作しました

見た目はだいたい一緒です

multirange

値の取得と設定はプロパティのみのサポートで from と to を使います
両方まとめては value です
バーの両端は min と max に指定します

const mr = document.querySelector("multi-range")
mr.from
// 20

mr.to
// 80

mr.value
// 20,80

mr.value = "30,70"

mr.from
// 30

mr.to
// 70

<!doctype html>

<script>

customElements.define("multi-range", class extends HTMLElement {
connectedCallback() {
if (this.shadowRoot) return

this.attachShadow({mode: "open"}).innerHTML = `
<style>
:host {
display: inline-block;
width: 300px;
--line-inactive: #ddd;
--line-active: deepskyblue;
--thumb: dodgerblue;
}
input[type="range"] {
width: 100%;
height: 30px;
cursor: pointer;
outline: none;
-webkit-appearance: none;
}
input[type="range"]::-webkit-slider-runnable-track {
height: 8px;
}
input[type="range"]::-webkit-slider-thumb {
height: 24px;
width: 24px;
margin-top: -8px;
background: var(--thumb);
border-radius: 50%;
box-shadow: 0 0 5px 0 #0003;
-webkit-appearance: none;
}

.container {
width: 100%;
position: relative;
}
#back, #front {
position: absolute;
top: 0;
left: 0;
}
#back::-webkit-slider-thumb,
#front::-webkit-slider-thumb {
position: relative;
z-index: 1;
}
#back::-webkit-slider-runnable-track {
background: linear-gradient(to right, var(--line-inactive) 0% var(--min),
var(--line-active) var(--min) var(--max),
var(--line-inactive) var(--max) 100%);
}
#front,
#front::-webkit-slider-runnable-track {
background: transparent;
}
</style>

<div class="container">
<input id="back" type="range" min="0" max="100" value="20" />
<input id="front" type="range" min="0" max="100" value="80" />
</div>
`

this._elems = {
back: this.shadowRoot.getElementById("back"),
front: this.shadowRoot.getElementById("front"),
}

this._elems.back.addEventListener("input", () => { this._redraw() })
this._elems.front.addEventListener("input", () => { this._redraw() })
this._redraw()
}

_redraw() {
const { min, max, from, to } = this
const x = (from - min) / (max - min) * 100
const y = (to - min) / (max - min) * 100

this._elems.back.style.setProperty("--min", x + "%")
this._elems.back.style.setProperty("--max", y + "%")
}

get min() {
return this._elems.back.min
}

set min(value) {
const [min, max] = [+value || 0, this.max].sort((a, b) => a - b)
this._elems.back.min = min
this._elems.back.max = max
this._elems.front.min = min
this._elems.front.max = max
this._redraw()
}

get max() {
return this._elems.back.max
}

set max(value) {
const [min, max] = [this.min, +value || 0].sort((a, b) => a - b)
this._elems.back.min = min
this._elems.back.max = max
this._elems.front.min = min
this._elems.front.max = max
this._redraw()
}

get from() {
return Math.min(this._elems.back.value, this._elems.front.value)
}

set from(value) {
const [min, max] = [+value || 0, this.to].sort((a, b) => a - b)
this._elems.back.value = min
this._elems.front.value = max
this._redraw()
}

get to() {
return Math.max(this._elems.back.value, this._elems.front.value)
}

set to(value) {
const [min, max] = [this.from, +value || 0].sort((a, b) => a - b)
this._elems.back.value = min
this._elems.front.value = max
this._redraw()
}

get value() {
return [this._elems.back.value, this._elems.front.value].sort((a, b) => a - b).join(",")
}

set value(value) {
const [min, max] = value.split(",").slice(0, 2).sort((a, b) => a - b)
this._elems.back.value = min
this._elems.front.value = max
this._redraw()
}
})

</script>

<multi-range></multi-range>