作りたいもの
つまみを非表示もどきにして丸っこくしたい
動作確認環境
コード
<input type="range" value="0" min="0" step="1" max="5" />
input[type="range"] { -webkit-appearance: none; /* デフォルトのCSSをリセット */ --range-height: 20px; --range-width: 250px; width: var(--range-width); height: var(--range-height); border-radius: 10px; background-color: skyblue; cursor: pointer; /* つまんでる感を出す(←?) */ /* つまみのCSS */ &::-webkit-slider-thumb { -webkit-appearance: none; /* デフォルトのCSSをリセット */ width: 0; /* つまみを非表示に見せるため0にする */ height: 0; /* つまみを非表示に見せるため0にする */ border: calc(var(--range-height) / 2) solid blue; /* range の半分の高さで先っちょの丸みを作る */ border-radius: 50%; } &:focus { outline: none; } }
デフォルトの CSS をリセットしたら、つまみの前後で色の変化がなくなるの悲しみ。
ということで JS でつまみの前後の色を変える。
(() => { const input = document.querySelector('input[type="range"]'); const min = input.min; const max = input.max; const width = parseInt(window.getComputedStyle(input).width); setRangeStyle(input, min, max, width); input.addEventListener("input", () => { setRangeStyle(input, min, max, width); }); })(); function setRangeStyle(input, min, max, width) { const border = (width / max) * input.value; // グラデの変化を急にしてつまみの前後を再現する input.style.background = `linear-gradient(90deg, blue ${border}px, skyblue ${border}px)`; }
やったねたえちゃん!完成だよ!
⊂ 二二二( ^ ω ^)二二 ⊃ ブーン
(^ ω ^) おっ?
(´・ω・`)・・・?
Σ(゜ □ ゜;)ナンテコッタイ!!!
適当な div を作って step の箇所を確認してみる2
ズレてやがる・・・
多分、開始と終了で border radius の起点が変わるから、中間点で調整されていってズレてくっぽい(伝われ)
ズレないようにつまみの位置を調整してみる
input[type="range"] { -webkit-appearance: none; --range-height: 20px; --range-width: 250px; width: var(--range-width); height: var(--range-height); --slider-thumb-right: var(--range-width); /* 追加。初期値をrangeでみたときに0始まりになるようにする */ border-radius: 10px; background-color: skyblue; cursor: pointer; position: relative; /* 追加 */ &::-webkit-slider-thumb { position: absolute; /* 追加 */ top: 0; /* 追加 */ right: var(--slider-thumb-right); /* 追加 */ -webkit-appearance: none; width: 0; height: 0; border: calc(var(--range-height) / 2) solid blue; border-radius: 50%; } &:focus { outline: none; } }
(() => { const input = document.querySelector('input[type="range"]'); const min = input.min; const max = input.max; const style = window.getComputedStyle(input); const width = parseInt(style.width); const height = parseInt(style.height); setRangeStyle(input, min, max, width, height); input.addEventListener("input", () => { setRangeStyle(input, min, max, width, height); }); })(); function setRangeStyle(input, min, max, width, height) { const border = (width / max) * input.value; // グラデの変化を急にしてつまみの前後を再現する input.style.background = `linear-gradient(90deg, blue ${border}px, skyblue ${border}px)`; let right = height / 2; if (input.value === min) { right = height; // つまみの起点 = rangeの最小値と同じ } else if (input.value === max) { right = 0; // つまみの終点 = rangeの最大値と同じ } input.style.setProperty( "--slider-thumb-right", `calc(${(width / max) * (max - input.value)}px - ${right}px)` ); }
✌✌✌
CodePen
See the Pen input range by m1y474 (@m1y474) on CodePen.
最後に
このブログ書いてるときに、JS使わずにワイがやりたいことやってる人見つけて鬱\(^o^)/
See the Pen Input Range with Gradient colors (CSS) by Victoria Azola Silva (@VickyAzola) on CodePen.
追記
でも↑これだとグラデの割合が絶対的にしか指定できないっぽい!ワイの作ったやつなら相対的にできるゾ!メンタル保てる!!
See the Pen input range gradient by m1y474 (@m1y474) on CodePen.