意外と知られていないtype="number"入力欄の5つの問題点

inputタグのtype="number"は数値の入力欄

inputタグで数値だけの入力欄が必要な際に正しく入力されるようtype="number"が指定されていることがある。

type="number" を指定すればChromeだとアルファベットなどが入力されず、スマートフォンだとキーボードが数字に切り替わって入力しやすくなるので入力ミスを減らせる。

しかし、inputタグのtype="number"はブラウザによって挙動が異なるので、そのまま使用すると問題が発生する可能性がある。

問題1 アルファベットが入力可能

type="number" を指定すれば数値だけ入力可能だと思われがちだが、実際はChromeではアルファベットは入力されないが、SafariやFirefoxは入力できる。

しかもSafariやFirefoxではアルファベットが含まれると空文字と判定されるので、例えば「I234」のようにアルファベットの「I」が含まれるとJavaScriptで取得した際に空文字と判定される。

input type="number" 入力チェックサンプル

問題2 全角数字が入力可能

Chromeだと入力不可だが、SafariやFirefoxでは全角数字を入力可能。

やっかいなことにSafariはアルファベットと同じく全角数字が含まれると空文字と判定されるが、Firefoxだと全角数字を半角数字として自動変換してしまう。

そのため「1234」と入力したらSafariは空文字でFirefoxは「1234」で取得してしまう。

input type="number" 入力チェックサンプル

問題3 Firefoxだと表示が崩れる

Firefoxだとフォントサイズを2remなどに変更すると表示が崩れる。

最新のFirefoxでも崩れるのでFirefoxのみに@-moz-document url-prefix()でpaddingを追加で適用させるなどの調整が必要になる。

/* 調整例 */
@-moz-document url-prefix() {
  input[type="number"] {
    padding: 0 1rem;
  }
}

問題4 スピンボタンで先頭の0が消える

type="number" は type="text" と異なり入力欄の右にスピンボタン(上下ボタン)が追加される。

この上下ボタンは「0123」のように先頭が付いている場合に1加算すると「124」のように0が除外されてしまう。

さらに電話番号のように「080-1234-5678」は0だとみなされ、1加算すると1となってしまうため押し間違いなどにより消去してしまう問題もある。

通常の入力フォームの数字の入力であればスピンボタンを使用する機会はほとんどないので、スピンボタンを非表示にするCSSを記述しておいたほうが良いだろう。

input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  appearance: none;
  margin: 0;
}
input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}

input type="number" 入力チェックサンプル

※ ちなみに2015年頃だとtype="number"は先頭に0が入力できないという問題もあったが、最近のブラウザはちゃんと入力できるようになっているので問題ない。

問題5 マイナス以外のハイフンは空文字判定

-123のようにマイナス値を入れる際ハイフン ( - ) を使用することがあると思うが、ハイフンを先頭以外に付けると空文字と判定される。

例えば電話番号の入力欄にtype="number"を使用して「080-1234-5678」を入力すると空文字として取得してしまう。

そのため先頭以外にハイフンが付いた場合はJavaScriptで除去する処理を入れたほうが良い。

const n = document.getElementById('n')

n.addEventListener('keydown', e => {
  const val = n.value
  if (e.code === 'Minus') {
    setTimeout(() => {
      n.value = val
    })
  }
})

あとChromeだとハイフンは2つまでしか入力できないので、123-45-67-89のような入力はできないので注意が必要。

input type="number" ハイフン除去サンプル