【JavaScript】input type=”number”でmaxlengthを使う方法

<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(指数)・+-・小数点を受け付け、先頭のゼロは消えます0077)。そのため「ちょうど5桁」のような桁数を固定したい用途には向いていません

おすすめ:type=”text” + inputmode=”numeric”

桁数を固定したい数値入力は、type="text" にして inputmode="numeric" を付けるのが最適解です。maxlength がそのまま効くうえ、スマートフォンでは数字キーパッドが表示され、先頭ゼロも保持されます。

HTML:桁数固定の数値入力(推奨)
<!-- 例: 5桁の数字(郵便番号・確認コードなど) -->
<input type="text" inputmode="numeric" pattern="\d*" maxlength="5">

inputmode="numeric" がモバイルのキーボードを数字に、pattern="\d*" が数字のみのバリデーションに、maxlength="5" が5文字までの制限になります。数字以外の入力を確実に弾きたい場合は、input イベントで取り除きます。

JavaScript:数字以外を自動で除去
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 は小数点やマイナスも含むため、数字だけを取り出してから桁数を数えるのがポイントです。

JavaScript:数字の桁数で制限する
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値の上限であって桁数の制限ではありません

HTML:maxは値の上限
<!-- 99999 までの「値」を許可(桁数制限ではない) -->
<input type="number" max="99999">

max="99999" は「99999以下の数値」という意味で、スピナーやフォーム送信時の検証に効きますが、キー入力そのものは止めません。「ちょうどN桁」を表したいなら、前述の type="text"maxlength が適切です。maxlength 属性そのものの扱いはmaxlengthやminlength属性を削除する方法で解説しています。

スピナー(増減ボタン)を消すCSS

type="number" の右側に出る増減ボタンを消したいときは、CSSで非表示にします。

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)

Qinput type=”number”でmaxlength属性が効かない理由は?
Amaxlength はテキスト入力向けのHTML属性で、type="number" には対応していないためです。桁数を固定したいなら type="text"inputmode="numeric"maxlength が最適です。
Q数値入力の桁数をJavaScriptで制限するには?
Ainput イベントで value.replace(/\D/g, "") により数字だけにしてから、slice(0, 桁数) で切り詰めます。小数点やマイナスを1文字に数えないよう、数字以外を除去してから桁数をチェックするのがポイントです。
Q先頭にゼロのある数値(007など)を入力させたいのですが?
Atype="number" は先頭ゼロを消してしまいます。007 のような表記を保持したいなら、type="text"inputmode="numeric" を使ってください。
Qスピナーを非表示にして数値入力をテキスト風にするには?
ACSSの input[type=number]::-webkit-inner-spin-button::-webkit-outer-spin-buttonappearance: none にします。Firefoxには input[type=number] { -moz-appearance: textfield; } が必要です。

まとめ

type="number"maxlength が効かないのは仕様です。桁数を固定したい数値入力(郵便番号・暗証番号・確認コードなど)は、type="text" inputmode="numeric" maxlength="5" を使うのが最適解で、モバイルの数字キーパッドや先頭ゼロにも対応できます。

どうしても type="number" を使う場合は、input イベントで数字だけを取り出してから桁数を制限します。max 属性は値の上限であって桁数ではない点にも注意しましょう。