<input type="number"> に maxlength を付けても効きません。これは仕様どおりの動作です。では、数値入力で桁数を制限したいときはどうすればよいのでしょうか。
結論を先に言うと、そもそも桁数固定の数値入力に type="number" は不向きです。郵便番号・暗証番号・確認コードなどは type="text" + inputmode="numeric" を使うのが正解です。この記事ではその理由と、どうしても type="number" を使う場合の対処まで解説します。
<input type="text" inputmode="numeric" maxlength="5"> が最適です。maxlength がそのまま効き、モバイルで数字キーパッドも出て、先頭ゼロも保持されます。type="number" を使うなら input イベントでJSで制限します(max 属性は「値の上限」で桁数とは別物)。なぜtype=”number”でmaxlengthが効かないのか
maxlength はテキスト系の入力(text / tel / search など)専用の属性で、HTMLの仕様上 type="number" には適用されません。
そもそも type="number" は「数量」を入れるための型で、e(指数)・+・-・小数点を受け付け、先頭のゼロは消えます(007 → 7)。そのため「ちょうど5桁」のような桁数を固定したい用途には向いていません。
おすすめ:type=”text” + inputmode=”numeric”
桁数を固定したい数値入力は、type="text" にして inputmode="numeric" を付けるのが最適解です。maxlength がそのまま効くうえ、スマートフォンでは数字キーパッドが表示され、先頭ゼロも保持されます。
<!-- 例: 5桁の数字(郵便番号・確認コードなど) --> <input type="text" inputmode="numeric" pattern="\d*" maxlength="5">
inputmode="numeric" がモバイルのキーボードを数字に、pattern="\d*" が数字のみのバリデーションに、maxlength="5" が5文字までの制限になります。数字以外の入力を確実に弾きたい場合は、input イベントで取り除きます。
const input = document.querySelector('input[inputmode="numeric"]');
input.addEventListener("input", () => {
input.value = input.value.replace(/\D/g, ""); // 数字以外を削除
});
電話番号など、入力タイプの選び方はinput type=”tel”の使い方も参考になります。
どうしてもtype=”number”を使うなら(JSで制限)
スピナー(増減ボタン)が必要などの理由で type="number" を使う場合は、JavaScriptで桁数を制限します。ただし type="number" の value は小数点やマイナスも含むため、数字だけを取り出してから桁数を数えるのがポイントです。
const numberInput = document.getElementById("numberInput");
const maxDigits = 5;
numberInput.addEventListener("input", () => {
// 数字だけを取り出して maxDigits 桁に切り詰める
const digits = numberInput.value.replace(/\D/g, "").slice(0, maxDigits);
if (numberInput.value !== digits) {
numberInput.value = digits;
}
});
value.length だけで判定すると、小数点 . やマイナス - も1文字として数えてしまいます("12.34" は 5 文字)。replace(/\D/g, "") で数字だけにしてから数えると正確です。入力をリアルタイムに監視して文字数を数える方法はフォーム入力をリアルタイムで監視する方法で詳しく解説しています。
max属性との違い(値の上限であって桁数ではない)
「数値の上限なら max 属性では?」と思うかもしれませんが、max は値の上限であって桁数の制限ではありません。
<!-- 99999 までの「値」を許可(桁数制限ではない) --> <input type="number" max="99999">
max="99999" は「99999以下の数値」という意味で、スピナーやフォーム送信時の検証に効きますが、キー入力そのものは止めません。「ちょうどN桁」を表したいなら、前述の type="text" + maxlength が適切です。maxlength 属性そのものの扱いはmaxlengthやminlength属性を削除する方法で解説しています。
スピナー(増減ボタン)を消すCSS
type="number" の右側に出る増減ボタンを消したいときは、CSSで非表示にします。
/* Chrome / Safari / Edge */
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
input[type="number"] {
-moz-appearance: textfield;
}
よくある質問(FAQ)
maxlength はテキスト入力向けのHTML属性で、type="number" には対応していないためです。桁数を固定したいなら type="text" + inputmode="numeric" + maxlength が最適です。input イベントで value.replace(/\D/g, "") により数字だけにしてから、slice(0, 桁数) で切り詰めます。小数点やマイナスを1文字に数えないよう、数字以外を除去してから桁数をチェックするのがポイントです。type="number" は先頭ゼロを消してしまいます。007 のような表記を保持したいなら、type="text" + inputmode="numeric" を使ってください。input[type=number]::-webkit-inner-spin-button と ::-webkit-outer-spin-button で appearance: none にします。Firefoxには input[type=number] { -moz-appearance: textfield; } が必要です。まとめ
type="number" で maxlength が効かないのは仕様です。桁数を固定したい数値入力(郵便番号・暗証番号・確認コードなど)は、type="text" inputmode="numeric" maxlength="5" を使うのが最適解で、モバイルの数字キーパッドや先頭ゼロにも対応できます。
どうしても type="number" を使う場合は、input イベントで数字だけを取り出してから桁数を制限します。max 属性は値の上限であって桁数ではない点にも注意しましょう。

