PR

input type=”number”は数字以外も入力できてしまう【解決法も解説】

HTML/CSSを学ぶ

こんにちは。今回はinputタグの細かい仕様についてです。

皆さんは<input type="number"> を使えば数字専用の入力欄が作れると思っていませんか?実は厳密には数字以外の入力も許容してしまいます。本記事ではtype="number" の仕様や適切な使い方、代替案について解説します。

type="number" の仕様

数字専用ではない?

<input type="number"> は一見すると数字だけを入力できる入力フィールドのように思われますが、実際には以下の文字が入力可能となっています。

  • 小数点 .(例: 3.14)
  • 負号 –(例: -5)
  • 加算記号 +(例: +5)
  • 指数記号 e または E(例: 1e5、-3.14E3)

この仕様を見ると分かる通り、数字ではなく数値を入力するためのものと考えられます。試しに下のinputで1.5や5e2などを試してみてください。

上記の文字は確かに数値を扱う際に便利です。しかし用途によっては不適切な挙動となる場合があります。例えば電話番号や数量の入力ではこれらの文字が誤入力の原因になりますよね。そういった場合は他の方法を検討する必要があります。

また、入力エリア右端にスピンボタンが現れます。押すと数値を上下させることができるボタンですが、これの存在が適切かどうかも使用すべきかの判断に役立ちます。

参考:https://developer.mozilla.org/ja/docs/Web/HTML/Element/input/number

数値入力を制御するための属性

<input type="number"> には、数値入力を制御するためにいくつかの属性が用意されています。

これらを適切に組み合わせることで、用途に応じた制限を設定できます。

  • min:最小値を指定します。例えばmin="0" と設定すると0未満の数値を許容しなくなります。
  • max:最大値を指定します。例えばmax="100" と設定すると100を超える数値を許容しなくなります。
  • step:許容される数値の間隔とスピンボタンの増減幅を指定します。例えばstep="1" と設定すると1刻みでの入力=整数のみを許容する挙動になり、step="10" と設定すると10刻みの値のみを許容する形になります。

厳密には入力そのものを制限するのではなく送信時にエラーを出す形です。フォーカスを外すとinputタグがinvalid状態になるので、CSSの擬似クラス:invalidを利用することができます。

input:invalid {
  background-color: red;
}

以下にmin=”0″ max=”100″ step=”1″の例を置きます。これは0から100までの正の整数のみを許可します。

:invalidを使って、1.1や3e5などの許容されない入力をすると背景が赤くなるようにしています。

これらの属性を適切に設定することでユーザーが意図しない値を入力するリスクを軽減できます。

type="number" を使うべきケース

上記のような仕様のため、<input type="number"> を正しく使うためにはその用途を限定する必要があります。以下のような場面での利用が適しています。

1 数量や金額

  • 商品の数量
  • 在庫の個数
  • シンプルな金額入力(通貨記号やカンマが不要な場合)
<label for="quantity">数量:</label>
<input 
  type="number" 
  id="quantity" 
  name="quantity" 
  min="0" 
  step="1" 
  placeholder="例: 5"
>

2 パーセンテージやスコア

  • 割引率や進捗率
  • テストの点数
<label for="discount">割引率:</label>
<input 
  type="number" 
  id="discount" 
  name="discount" 
  min="0" 
  max="100" 
  step="0.1" 
  placeholder="例: 10"
>

3 科学的データや技術計算

  • 指数表記が必要な場面(例: 1e5
  • 測定値や計算値
<label for="scientific">科学データ:</label>
<input type="number" id="scientific" name="scientific">

type="number" を避けるべきケース

観点としては、

  • 数値ではない
  • スピンボタンの存在が不自然である

という状況では使わない方がいいでしょう。以下のような場面ではtype="number" の使用を避けるべきです。

1 電話番号

  • そもそもtype="tel"がある
  • type="number"ではpattern属性が使えず簡易的なバリデーションもできない

ということでtype="number" は適していません。

<label for="phone">電話番号:</label>
<input 
  type="tel" 
  id="phone" 
  name="phone" 
  pattern="^0\d{9,10}$"
  title="電話番号の形式が正しくありません。もう一度ご確認の上、再度入力してください。"
  placeholder="09012345678"
>

ちなみにtitle属性はエラー時の情報を補足することが出来ます(下画像)。

もしくはsetCustomValidity()を使ってきちんとメッセージを変えてしまってもいいでしょう。

const phone = document.getElementById("phone");
phone.setCustomValidity("電話番号の形式が正しくありません。もう一度ご確認の上、再度入力してください。");

2 固定フォーマットの数字(郵便番号やクレジットカード番号)

郵便番号やクレジットカード番号などは数字ではありますが数値ではありませんよね。

またフォーマットを厳密に管理する必要があるため、例えばtype="text" と正規表現を使う方法が適切です。場合によってはもっと複雑なフォームを用意することもあります。

<label for="postal">郵便番号:</label>
<input 
  type="text" 
  id="postal" 
  name="postal" 
  pattern="\d{3}-\d{4}" 
  placeholder="例: 123-4567"
>

まとめ

type="number" は便利な要素ですが、その仕様を正しく理解し適切な場面でのみ使用することが重要です。

  • 使うべき場面: 数量やパーセンテージなど、純粋な数値を扱う場合。
  • 避けるべき場面: 電話番号や固定フォーマットが必要な入力。

適切な使い方を意識することで、ユーザー体験の向上とバグの防止につながります。

コメント

タイトルとURLをコピーしました