input[type=number]を使う前に考えること

input[type=number]を使うべき要件と、数字だけで構成される文字列を入力してもらう場合の実装を整理します。

Published
2023年12月27日
Read in English

クレジットカード番号の入力欄を input[type=number] で作ると、フォーカスした状態でホイールを回すだけで値が変わります。桁数を間違えても、どこがおかしいのかは画面に出ません。私はこの要素の用途を誤解したまま使っていたので、選ぶ基準を整理します。

input[type=number] はスピンボタンである

値を一定量ずつ増減する操作が役立つ場合に、input[type=number] を使います。MDNでも、数値を段階的に増減する用途へ使うよう説明されています。

<input type=“number”> 要素の暗黙のロールは spinbutton (en-US) です。もしスピンボタンがフォームコントロールにとって重要な機能でないなら、 type=“number” を使用しないよう検討してください。代わりに inputmode=“numeric” を使用し、 pattern 属性で文字列を数字とそれに付随する文字に限定してください。 <input type=“number”> では、ユーザーが何か他のことをしようとしているときに、誤って数値を増加してしまう危険性があります。さらに、ユーザーが数字でないものを入力しようとした場合、何が間違っているのか明示的なフィードバックがありません。

この要素には暗黙のARIAロールとして spinbutton が付与されます。「数字だけを入力する欄」ではなく、範囲内の数値を増減できる入力です。

商品の個数のように増減操作が適しているなら、まずネイティブの input[type=number]minmaxstep の利用を検討します。見た目を変えたいという理由だけで独自の role="spinbutton" を作ると、キーボード操作や値の通知まで自前で実装する必要があります。

数字の入力をしたい場合

クレジットカード番号や郵便番号は数字だけで構成されますが、計算に使う「数値」ではありません。このような値には type="text" を使い、必要に応じて inputmode="numeric" で数字向けの仮想キーボードを提示します。桁数などの制約には pattern を利用できます。

入力条件は、title 属性だけに頼らず、画面上の説明として示したうえで aria-describedby から関連付ける方が確実です。ユーザーが入力する前に条件を理解できるようにします。

<form>
  <input name="digit" type="text" pattern="[\d]{3}" title="3 digit number" />
  <button>submit</button>
</form>

<form>
  <input
    name="digit"
    type="text"
    pattern="[\d]{3}"
    aria-describedby="digit-description" />
  <span id="digit-description">3 digit number</span>
  <button>submit</button>
</form>

独自のエラーメッセージを表示する場合は、入力欄とメッセージを aria-describedby で関連付け、無効な状態を aria-invalid で伝えます。送信後などに動的にメッセージを追加する場合は、role="status"aria-live の利用も検討します。

<label>
  <input
    name="digit"
    type="text"
    inputmode="numeric"
    pattern="\d{3}"
    aria-invalid="true"
    aria-describedby="digit-error" />
  <p id="digit-error" role="status" aria-live="polite">
    <span>3 digit number</span>
  </p>
</label>

判断の基準は、その値を数値として扱うか、増減操作が役立つかです。見た目が数字であることは基準になりません。input[type=number] が扱いづらかったのではなく、想定されていない用途へ使っていたことが問題でした。

input[type=date]を選ぶときの注意

少し寄り道して、input[type=date] にも触れます。送信される値は、表示形式にかかわらず yyyy-mm-dd 形式の日付文字列、または空文字です。表示されるUIや操作方法は、ブラウザとOSによって異なります。

まずは、ローカライズやキーボード操作をブラウザに任せられるネイティブ入力を検討します。特定の日付だけを選べるようにする、複数の日付を扱うなど、要件を満たせない場合に限ってDate Pickerを検討します。独自実装ではアクセシビリティと操作性の確保が難しいため、見た目だけを理由に置き換えない方が安全です。

さいごに

使い慣れた要素ほど、わかったつもりになります。入力要素は、見た目ではなく、値の意味とユーザーが行う操作で選びます。

参考文献