![input[type="number"]における全角入力対応をChromium/WebKitへ提案と実装をした話 アイキャッチ](https://www.fourier.jp/storage/blog/post-outline/72p4chSEDv2ghmnU9xADoSgwBWvhGumO.jpg) 
        Intro
    サイトを作成する際、    input    タグのRangeスライダーを縦に配置したくなる場面が稀にあると思います。
    
 
    この記事では、スライダーを縦に表示する2種類の方法とそれぞれの問題点、そしてレスポンシブ対応について解説します。
方法
縦スライダーを表示するには主に以下の2通りがあります。
- 
    webkit-appearanceで設定
- 
    transformで回転させる
それぞれの方法と問題点について解説します。
webkit-appearance
2021年の9月末、Firefoxを除くChromeやSafariなどの主要ブラウザが縦スライダーの表示をサポートしました。
    やり方は簡単で、    input    のCSSプロパティに    -webkit-appearance: slider-vertical    を設定すれば縦方向に表示されます。
    
input[type=range].vertical {
  -webkit-appearance: slider-vertical;
}以下が実際に動作するデモです。
この方法の利点として、後述する回転させるやり方と比較すると、親要素が回転後のスライダーの大きさに合うためレスポンシブ対応がしやすいという利点があります。
ただ、以下のような多くの欠点があります。
- Firefoxがこの文法に対応していない
- thumb(丸い部分)のスタイリングが効かない
- track(thumbの可動範囲)が細すぎると表示が崩れる
現状この機能を使うにはまだ時期尚早と言え、実用的な解決策とは言えません。
transform
    次に、昔からある方法として、    input    要素のCSSプロパティに    transform: rotate(-0.25turn);    を追加する方法があります。これはスライダーを90°回転させて表示させるやり方です。
    
input[type=range].vertical {
  transform: rotate(-0.25turn);
}
    このやり方に    webkit-apparance    で発生したスタイリングが当たらない問題や対応ブラウザの問題はないため、こちらのほうが実用的です。
    
ただ、そのままだと以下の例のように親要素をはみ出してしまいます。
    これは、親要素の大きさが回転前の    input    タグの大きさに合わせており、回転後のスライダーの大きさ(    height    、    width    が逆になる)に合ってないからです。
    
はみ出さないようにする
スライダーを親要素からはみ出さないようにする最も簡単な解決方法は、親要素の大きさをスライダーに合わせて指定する方法です。しかし、そのやり方だとレスポンシブ対応になっていないという問題があります。
レスポンシブなスライダーを作成するために、以下のコンポーネントと機能を実装します。
    まず、    input    要素をラップしたコンポーネントを作成します。そして、ラッパー要素の    width    、    height    プロパティを読み込み、    input    要素の    height    、    width    プロパティに適応させるJavaScriptコードを書きます。
    
customElements.define(
  'vertical-slider',
  class extends HTMLElement {
    get min() {
      return this.getAttribute('min') || 0;
    }
    
    set min(val) {
      this.setAttribute('min', val);
    }
    
    get max() {
      return this.getAttribute('max') || 100;
    }
    
    set max(val) {
      this.setAttribute('max', val);
    }

    get step() {
      return this.getAttribute('step') || 1;
    }
    
    set step(val) {
      this.setAttribute('step', val);
    }
    
    get value() {
      return this.getAttribute('value') || 50;
    }
    
    set value(val) {
      this.setAttribute('value', val);
    }
    
    render() {
      const input = document.createElement('input');
      input.setAttribute('type', 'range');
      input.setAttribute('min', this.min);
      input.setAttribute('max', this.max);
      input.setAttribute('step', this.step);
      input.setAttribute('value', this.value);
      
      wrapper.appendChild(input);
      
      const style = document.createElement('style');
      style.textContent = `
        :host {
          --width: 16px;
          --height: 175px;
        
          display: inline-block;
          position: relative;
          margin-right: calc(var(--width) / 2);
          width: var(--width);
          height: var(--height);
        }

        input[type=range] {
          position: absolute;
          left: 0;
          bottom: -0.75em;
          transform: rotate(-90deg) translateY(calc(var(--width) / 2));
          transform-origin: left;
          width: var(--height);
          height: var(--width);
        }
      `;
      
      const shadowRoot = this.attachShadow({mode: 'open'});
      shadowRoot.append(input);
      shadowRoot.append(style);
    }
    
    connectedCallback() {
        this.render();
    }

    attributeChangedCallback() {
        this.render();
    }
  }
)
    次に、親要素の    height    を読み取り、スライダーに適用させる機能を実装します。これは    ResizeObserver    というクラスを使用して実装します。
    
new ResizeObserver(entries => {
  const height = entries[0].contentRect.height;
  const slider = document.getElementById('vs');
  slider.setAttribute('style', `
    --height: ${height}px;
  `);
}).observe(document.getElementById('frame'));このコンポーネントによって、外側から見たときにレスポンシブに大きさが変化する縦スライダーを使用することができます。
<div class="container">
  <p>vertical</p>
  <div class="frame" id="frame">
    <vertical-slider id="vs"></vertical-slider>
  </div>
</div>これらをWeb Componentとして実装したのが以下のコードです。白い枠がリサイズできるようになっており、ドラッグしてスライダーの大きさが変わることが確認できます。
まとめ
    この記事では縦スライダーを表示する方法を    webkit-appearance    で設定する方法と    transform    で回転させる方法の2つを紹介し、それぞれの問題点を取り上げた後に、    transform    で回転させた場合のレスポンシブ対応について取り上げました。
    
    現状では実装するにはなかなか難易度が高く複雑なため、早く    -webkit-appearance: slider-vertical;    で設定できるようになってほしいと思います。
    
 
     
    ![今のところinput[type=”number”]を使わない方が良い理由と代替案 アイキャッチ](https://www.fourier.jp/storage/blog/post-outline/OlRJZKUrVhcZSaTzc1CW5EXQQAhummzX.jpg) 
         
         
        