HTML の適切な数字入力について調べてみた (type, inputmode, pattern)

適切な数字入力とは?

2022/7/25 更新

・ 論点を明確にするために、この記事で扱う郵便番号の仕様を、7桁の数字 => 3桁 + 4桁の数字 に変更しました。

Design Div 所属フロントエンドエンジニアの上垣です。

Webサービスを作成するにあたり、フォーム周りのユーザー体験は特に慎重に設計する必要があると考えています。なぜなら、フォームはユーザーとサービスをインタラクティブにつなぐ重要な接点であり、フォームの体験はサービス全体に対する印象に直結するからです。

そんな中で、郵便番号の入力フォームを作成する際、ふと「郵便番号の入力に適切な type は何だっけ?」と思い立ったので、調査してみました。

※この記事で想定している郵便番号の仕様 = 3桁 + 4桁の数字 (郵便番号を2つの input に分割するのは適切かという問題は、この記事では扱いません。)

type="number" は不適切

郵便番号は「数字のみ」で構成されるので、input 要素に type=”number” を指定してみます。

<input type="number" id="postal-code">

type=”number” の主な特徴を列挙してみます。

  • PCブラウザでは、フィールドの右側にスピンボックスが表示され、入力が数字と特定の記号に制限される

    macOS Chrome104 入力欄にスピンボックスが表示される

  • モバイルブラウザでは、フォーカスすると数字入力キーボードが表示される

    iOS15.5 Safari 数字入力キーボード

  • フォームの submit 時にバリデーションが実行され、数字以外が入力されている場合はサブミット処理が中断され、フィードバックが与えられる。

    iOS15.5 Safari 制約違反フィードバック

以上から、type=”number” を指定することで、「郵便番号の入力を数字に限定する」という目的は十分果たせそうなことがわかりました。 特にモバイルブラウザでは、フォーカス時に数字キーボードが表示されるので、ユーザー体験的にも良好そうです・・が、PC ブラウザでスピンボックスが表示される意図が気になります 🤔

HTML の仕様を確認してみると、「たまたま数字だけで構成されているが、厳密には数値ではない入力には適していません。」とあり、厳密な数値以外の入力に type=”number” を指定することは、推奨されないことがわかりました。確かに、郵便番号は、たまたま数字で構成されているだけで、実態は地域を分類・識別するための識別子です。なので、郵便場号の入力は、number ではなく、input type=”text” を指定するのが適切そうです。(他には、クレジットカード番号や、電話番号も数字ではなく識別子ですね)

仕様該当部分の引用(https://html.spec.whatwg.org/multipage/input.html#when-number-is-not-appropriate)

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.

type=”text” と inputmode 属性を組み合わせる

郵便番号の入力として、 type=”number” は適切でないことはわかりました。しかし、替わりに type=”text” を指定した場合、 type=”number” で得られていた以下の機能は失われてしまいます。

  1. モバイルブラウザでは、フォーカス時に数字入力キーボードが表示される。
  2. PC ブラウザでは入力値が数字(と一部の記号) に制限される。
  3. デフォルトでバリデーションがかかる

特に 1 は重要で、数字しか受け付けないのに、毎回キーボードを 「テキスト」 ⇒ 「数字」へ切り替えさせるのは、あまり望ましくないユーザー体験です。

調べてみると、この問題は、 inputmode 属性 を与えることで解決できることがわかりました。

inputmode 属性によって、ブラウザに、「表示するべき仮想キーボードのタイプ」を指定することができます。 数字キーボードを表示させたい場合は、inputmode=”numeric” を指定します。

<input type="text" id="postal-code" inputmode="numeric">

iOS15.5 Safari で、 inputmode="numeric" のフィールドをフォーカス

pattern 属性で制約を追加する

inputmode 属性を指定してもバリデーションは有効になりません。代替手段の一つとして、pattern 属性に正規表現を指定することで、入力に制約をかけることができます。

3桁の数字に制限する例

<input type="text" id="postal-code" pattern="[0-9]{3}">

macOS Chrome104

この場合、title 属性の値をフィードバックメッセージに追加してくれるブラウザもありますが、全てでは無いので、制約についての説明テキストも追加する必要があります。

まとめ

数字のみの入力を作成する場合は、値が「数値」「識別子」かを考慮して、適切な type 属性を選択する。 type="text" の場合は、inputmode で仮想キーボードの形式を、pattern 属性で入力値の制約を指定する。

  • 数値の場合 ⇒ input type=”number”
  • 識別子の場合 ⇒ input type=”text” + inputmode ( + pattern)

参考URL