見出し画像

📝数値という理由だけで input[type="number"] 要素を使わない

フォームに入力する値といえば、電話番号や年齢、クレジットカード番号など様々です。しかし、数字を使っているからといってむやみに <input type="number"> 要素を使うと問題が起きます。

数字であって数値でない

WHATWG の仕様には次のように書かれています。

The type=number state is not appropriate for input that happens to only consist of numbers but isn't strictly speaking a number. For example, it would be inappropriate for credit card numbers or US postal codes. A simple way of determining whether to use type=number is to consider whether it would make sense for the input control to have a spinbox interface (e.g. with "up" and "down" arrows). Getting a credit card number wrong by 1 in the last digit isn't a minor mistake, it's as wrong as getting every digit incorrect. So it would not make sense for the user to select a credit card number using "up" and "down" buttons. When a spinbox interface is not appropriate, type=text is probably the right choice (possibly with a pattern attribute).

要約すると、<input type="number"> 要素は増えたり減ったりする数値に使うべきであって、クレジットカード番号のような1桁違うだけで正しくなくなってしまう数値には意味をなさないということです。

<input type="number"> 要素を使うと、ブラウザによりますが、上矢印と下矢印の UI がデフォルトで表示されますよね。

画像1

つまり、この UI を使う場合があるかどうかが決め手となるわけです。

また、キーボードの上矢印キーと下矢印キーで数値の増減ができるため、クレジットカード番号に <input type="number"> 要素を使ってしまうと、誤って矢印キーに触れてしまった場合に値が変化してしまう恐れもあります。

大きな値は指数表記になる

桁数が多くなると、e+26 のような指数表記になってしまいます。

画像2

一度、指数表記に変換されてしまうと、矢印キーで値の増減ができなくなります。実際に 18 桁を超えるような数値を入力することはないかもしれませんが、期待されている動作と違うことは確かです。

また、<input type="number"> 要素には + - . が入力できますが、指数表記ができるということは e も数値として入力ができます。

document.querySelector('input[type="number"]').addEventListener('keydown', event => {
  if (event.key === 'e') {
    event.preventDefault()
  }
})

おそらく期待できる動作ではないため、JavaScript を使って e を入力できないようにしておくとよいと思います。

先頭の 0 が消える

Firefox では、value 属性に 0123 と指定があっても、先頭の 0 は無視されて表示されません。

画像3

<input type="number" value="0123">

また、他のブラウザでも初期表示状態では 0 が表示されていても、UI や矢印キーで値を増減させると、先頭の 0 が消えてしまいます。

画像4

どうすればよいか

結局、クレジットカード番号などの数字であって数値でないような値はどう表現すればよいのでしょうか。

<input type="text" inputmode="numeric" pattern="\d*">

現時点での最適解は、type 属性に text を指定し、inputmode 属性を使うことです。inputmode 属性に numeric を指定することで、iPhone や Android で入力するときに数字キーボードが表示されるようになります。

画像5

これにより、ユーザビリティの向上にもつながります。

また、pattern 属性は inputmode 属性に非対応の場合でも、数字キーボードが表示されるように指定しています。inputmode 属性の対応状況を見てみると、iOS12.2 から対応されており、まだ pattern 属性を指定しておく意味はありそうです。

今すぐ始めるCSSレシピブック

この記事が気に入ったらサポートをしてみませんか?