数値入力の input[type="number"] を作ったとします。
▼ 例えばこんな感じで定義できる
1 |
<input type="number" step="2" /> |
▼ デフォルト状態のスピンボタン
このスピンボタンは問題点があります。
- なんかデザインが少しだけダサい
- というかブラウザ依存になってしまう
- あとスマホでは一切表示されない
デフォルトだと上下矢印が表示されるだけだし、なによりスマホだと一切表示されないのが不便です。同じ考えの人は多いはずです。
そこでカスタマイズを試してみました。
▼ アレンジ後のスピンボタン例
このinput type="number"のスピンボタン、
それをカスタマイズする方法を紹介します。
このページの目次
手順1.スピンボタン用にinputのHTML構成を変更する
この方法ではHTML構成そのものに手を加えます。
▼ 変更前 : inputタグが1つだけあるだけ
1 |
<input type="number" step="2" /> |
▼ 変更後 : 次のような感じのHTML構成に変更
1 2 3 4 5 |
<label class="number-spinner-wrap"> <input type="number" step="2" value="16"> <span class="spinner spinner-down">-</span> <span class="spinner spinner-up">+</span> </label> |
各要素について簡単に説明します。
- .number-spinner-wrap
全体(input、左右スピンボタン)を囲むための要素。ここではlabelを使っているがdiv要素で囲んだとしても問題ない
- .input
変更前のinput要素と同じ。この例では step="2" を指定してるから、スピンボタン押下時に±2だけ増減させたい。
- .spinner-down, .spinner-up
カスタマイズされたスピンボタン。前者がクリックされたら数値を -2 、後者がクリックされたら数値を +2 する(デフォルト挙動に合わせる)
各要素はこういった役割を持ってます。
はじめはinput要素だけでカスタマイズしようと試したのですが、やはりラップ要素で囲んでスピンボタン要素を新しく追加する方法に落ち着きました。
このようなHTML構成にします。
手順2.input用のカスタマイズCSSを追加する
次にカスタマイズCSSを追加します。
▼ inputのカスタマイズCSS例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
/** input/スピンボタンのラップ要素 **/ .number-spinner-wrap{ position: relative; display: block; width: 150px !important; height: 2rem; } /** デフォルトのスピンボタンを隠す **/ .number-spinner-wrap input::-webkit-outer-spin-button, .number-spinner-wrap input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } /** input要素 **/ .number-spinner-wrap input{ width: 100%; height: 100%; padding-left: 3rem; padding-right: 3rem; text-align: center; } /** スピンボタン要素 **/ .number-spinner-wrap .spinner{ position: absolute; top: 50%; width: 1.2rem; transform: translate(0, -50%); font-size: 1rem; padding: 2px .5rem; text-align: center; background: lightgray; cursor: pointer; user-select: none; } /** 減算のスピンボタン要素 **/ .number-spinner-wrap .spinner-down{ left: 2px; border-right: 1px solid lightgray; } /** 加算のスピンボタン要素 **/ .number-spinner-wrap .spinner-up{ right: 2px; border-left: 1px solid lightgray; } |
特に説明するような箇所はありません。
長いだけで地道にカスタマイズしてるだけです。
でも1つだけ強調するなら input::-webkit-outer-spin-button, input::-webkit-inner-spin-button でデフォルトのスピン要素を隠してることですね。
それ以外は特筆することは本当にありません。
手順3.スピンボタン押下時の処理コードを追加する
これだけだとスピンボタンは機能しません。
スピンボタン押下時のJavaScriptコードを追加します。
▼ このようなJavaScriptコード
1 2 3 4 5 6 7 8 |
const $wrap = document.querySelector('.number-spinner-wrap') const $input = $wrap.querySelector('input') $wrap.querySelector('.spinner-down').onclick = ()=>{ $input.stepDown() } $wrap.querySelector('.spinner-up').onclick = ()=>{ $input.stepUp() } |
スピンボタン押下時の処理を定義してます。
重要なのは $input.stepDown() 、 $input.stepUp() を使うことでデフォルト挙動を再現してることです。スピンボタン押下時にinputの数値を操作できます。
これでカスタマイズはすべて完了です
実際のスピンボタンの挙動はこんな感じ(動画)
実際の見た目・挙動とかを載せておきます。
▼ デフォルトはダサい見た目だったのに……
▼ カスタマイズでこんな素敵な見た目に!
▼ 実際に動かしている様子(GIF)
スピンボタンが常時表示されるようになり、デフォルトのスピンを押下した時と同じように機能します。あとスマホでも隠れないから親切ですね。
以上、ここまでがカスタマイズ手順でした。