<input>で入力体験を上げるうえで効果が大きいのは、autocomplete・inputmode・enterkeyhintの3つを正しく書くことです。特にスマートフォンでは、この3つの有無で入力にかかる時間がはっきり変わります。
先に補足しておくと、inputmodeやautocompleteは2023年に追加された属性ではありません。どれも以前から仕様にあるもので、2023年前後に「全ブラウザで安心して使える状態になった」というのが正確なところです。この記事では、その使い方と、実装でつまずきやすい点をまとめます。
スポンサーリンク
type / inputmode / pattern の役割分担
この3つは似て見えますが、役割がまったく違います。混同すると「数字しか入らないはずの欄に文字が入る」「スマホでキーボードが切り替わらない」といった不具合になります。
| 属性 | 効くもの | 効かないもの |
|---|---|---|
type |
値の解釈、標準の検証、UI(カレンダー等) | — |
inputmode |
モバイルのソフトキーボードの種類 | 入力値の制限(見た目だけ) |
pattern |
送信時の形式チェック | キーボードの切替、入力そのものの禁止 |
実務でよく問題になるのが郵便番号・電話番号・クレジットカード番号です。これらにtype="number"を使うのは避けてください。理由は次の通りです。
- 先頭の
0が落ちる(0120が120になる) - ハイフンが入力できない
- スピナー(上下の矢印)が出る。マウスホイールで値が勝手に変わる
- 桁数の多い数値が指数表記になることがある
正解はtype="text"+inputmode="numeric"+patternです。
<!-- ❌ 郵便番号に type="number" は使わない -->
<input type="number" name="zip">
<!-- ✅ -->
<label for="zip">郵便番号</label>
<input type="text" id="zip" name="zip"
inputmode="numeric"
autocomplete="postal-code"
pattern="\d{3}-?\d{4}"
title="123-4567 または 1234567 の形式で入力してください"
maxlength="8">
type="number"が本当に向くのは、数量や年齢のように「増減させたい数値」だけです。その場合もmin / max / stepを必ず添えてください。
inputmode の主な値
| 値 | 出るキーボード | 用途 |
|---|---|---|
numeric |
数字のみ | 郵便番号、認証コード、カード番号 |
decimal |
数字+小数点 | 金額、体重 |
tel |
電話用キーパッド(*や#付き) | 電話番号 |
email |
@付き | メールアドレス |
url |
/や.com付き | URL |
search |
Enterが「検索」になる | 検索欄 |
none |
出さない | 自前のキーパッドを表示する場合 |
autocomplete を正しく書くと入力が一番速くなる
体感で最も効くのがこれです。 ブラウザやパスワードマネージャーが保存済みの住所・氏名・カード情報をワンタップで流し込めるようになります。
注意点は、autocomplete="on" や autocomplete="名前" のような自己流の値では効かないことです。仕様で決められたトークンを使う必要があります。
<input type="text" name="lname" autocomplete="family-name">
<input type="text" name="fname" autocomplete="given-name">
<input type="email" name="email" autocomplete="email">
<input type="tel" name="tel" autocomplete="tel">
<input type="text" name="zip" autocomplete="postal-code">
<input type="text" name="addr1" autocomplete="address-level1"> <!-- 都道府県 -->
<input type="text" name="addr2" autocomplete="address-level2"> <!-- 市区町村 -->
<input type="text" name="addr3" autocomplete="address-line1"> <!-- 番地 -->
ログイン・新規登録での指定
ここを間違えると、パスワードマネージャーが誤動作します。ログインと新規登録で値が違うことに注意してください。
<!-- ログイン -->
<input type="text" name="user" autocomplete="username">
<input type="password" name="pass" autocomplete="current-password">
<!-- 新規登録・パスワード変更 -->
<input type="password" name="new" autocomplete="new-password">
<!-- SMSで届く認証コード(自動入力される) -->
<input type="text" name="code"
inputmode="numeric" autocomplete="one-time-code" maxlength="6">
autocomplete="one-time-code"は、iOSやAndroidでSMSの認証コードを自動入力させるためのものです。これを入れるかどうかで、二段階認証の通過率がはっきり変わります。
スポンサーリンク
enterkeyhint でキーボードの実行キーを変える
スマートフォンのキーボード右下のキーは、既定では「改行」や「完了」です。enterkeyhintで「検索」「送信」「次へ」に変えられます。
<input type="search" enterkeyhint="search" placeholder="サイト内を検索">
<input type="text" enterkeyhint="next" name="lname">
<input type="text" enterkeyhint="next" name="fname">
<input type="email" enterkeyhint="send" name="email">
指定できるのは enter / done / go / next / previous / search / send です。多段のフォームでnextを並べるだけで、指の移動がかなり減ります。
datalist の限界を理解して使う
<datalist>は手軽な入力補完ですが、「候補以外も入力できてしまう」点を理解しておく必要があります。選択肢を強制したいなら<select>を使ってください。
<label for="pref">都道府県</label>
<input type="text" id="pref" name="pref" list="prefectures"
autocomplete="address-level1">
<datalist id="prefectures">
<option value="北海道"></option>
<option value="東京都"></option>
<option value="大阪府"></option>
<option value="福岡県"></option>
</datalist>
実際に使うときに知っておきたい制約です。
- 候補以外の値も送信できる:必須にしたいなら
patternやサーバー側で弾く - 候補リストの見た目はCSSで変えられない:ブラウザのUIそのものです
- 絞り込み方式はブラウザ依存:前方一致か部分一致かが統一されていません
- 件数が多いと使いづらい:数十件を超えるなら
<select>か自作のコンボボックスへ
スポンサーリンク
エラーメッセージを自分の言葉にする
ブラウザ標準のメッセージ(「このフィールドを入力してください」)は、そのままでは不親切なことがあります。setCustomValidity()で差し替えられます。
const zip = document.getElementById('zip');
zip.addEventListener('input', () => {
// 一度クリアしないと、直しても不正なままになる
zip.setCustomValidity('');
if (zip.validity.valueMissing) {
zip.setCustomValidity('郵便番号を入力してください');
} else if (zip.validity.patternMismatch) {
zip.setCustomValidity('ハイフンありなしどちらでも構いません(例: 123-4567)');
}
});
先頭でsetCustomValidity('')を呼ぶのが必須です。空文字を渡すまでその入力欄は「不正」のままになり、正しく直しても送信できなくなります。これは非常によく踏むバグです。
validityオブジェクトで、不正の理由を細かく判別できます。
| プロパティ | 意味 |
|---|---|
valueMissing |
requiredなのに空 |
typeMismatch |
emailやurlの形式違反 |
patternMismatch |
patternに一致しない |
rangeUnderflow / rangeOverflow |
min / max の範囲外 |
tooShort / tooLong |
minlength / maxlength 違反 |
stepMismatch |
stepの刻みに合わない |
ファイル入力と、値の取り出し方
ファイル選択ではacceptで拡張子やMIMEタイプを絞り込めます。スマートフォンではcaptureでカメラを直接起動できます。
<!-- 画像だけを選ばせる -->
<input type="file" name="photo" accept="image/*" multiple>
<!-- スマホでカメラを直接起動(背面カメラ) -->
<input type="file" name="doc" accept="image/*" capture="environment">
acceptはあくまでファイル選択ダイアログの絞り込みで、検証ではありません。ユーザーは「すべてのファイル」に切り替えられます。サーバー側で必ず種類とサイズを確認してください。
日付や数値の値は、文字列ではなく専用のプロパティで取ると扱いが楽になります。
const num = document.getElementById('num');
const day = document.getElementById('day');
num.valueAsNumber; // number(空なら NaN)
day.valueAsDate; // Date オブジェクト(UTC基準なので時差に注意)
トグルスイッチは switch 属性を使えるか
まだ本番では使えません。 <input type="checkbox" switch> は Safari 17.4 で搭載されましたが、2026年9月時点でChrome と Firefox は未対応です。
ただし、未対応ブラウザでは普通のチェックボックスとして正しく動作するため、段階的強化として書いておくのは安全です。
<label>
<input type="checkbox" switch name="notify" checked>
通知を受け取る
</label>
全ブラウザで同じ見た目のスイッチが必要なら、現状はCSSで作ることになります。その場合もappearance: noneで作り直すより、accent-colorで色だけ変えたチェックボックスの方が、キーボード操作とスクリーンリーダー対応の面では堅実です。
まとめ
- 郵便番号・電話番号・カード番号に
type="number"を使わない。type="text"+inputmode="numeric"+pattern autocompleteは仕様の決まったトークンで書く。current-passwordとnew-passwordを取り違えない- SMS認証には
autocomplete="one-time-code" enterkeyhintでキーボードの実行キーを「次へ」「検索」に変える<datalist>は候補以外も入力できる。強制したいなら<select>setCustomValidity()は毎回空文字でクリアしてから設定するacceptは検証ではない。サーバー側で必ず確認するswitch属性はSafariのみ。段階的強化としてなら書ける
フォーム全体の設計や:user-invalidによるエラー表示はHTML form要素の新機能と活用法に、確認ダイアログの実装はdialog要素の使い方にまとめています。