HTML数値入力:min・max・stepと小数・valueAsNumber

HTML input type="number" は比較または増分が可能な数量を受け入れます。min と max は範囲を設定し、step は有効な間隔を設定します。小数を許可するには、間隔とその基準の両方を考慮する必要があります。数字のように見える電話番号や郵便番号には、通常別の入力タイプが必要です。

min · max · step

min および max は、範囲外の数字の入力を必ずしも防ぐわけではありません。無効な値が入力された場合でも、通常のフォーム送信はバリデーションによってブロックされます。値が空であってはならない場合は、required を追加してください。

stepの基準値は、有効なminがあればその値、なければHTMLの有効なvalue属性、どちらもなければ0です。基準値から間隔の整数倍だけ離れた値が有効です。既定の間隔は1ですが、基準値が小数なら有効な値も小数になり得るため、既定値で小数がすべて禁止されるわけではありません。

設定 有効な値の例 注意
min="0" step="1" 0、1、2 0.5 は範囲に合いません。
min="0" step="0.01" 1、1.2、1.23 1.234 は合いません。これは小数点以下2桁の表示を強制するものではありません。
min="0" step="3" 0、3、6、9 ゼロを基準とした三の倍数。
min="1" step="3" 1、4、7、10 基準が1なので、これらは三の倍数とは異なります。
step="any" 範囲内のさまざまな小数値 ステップ制約を削除します。その他の範囲および必須の制約は残ります。

1つの例で整数と小数の入力を比較する

この完全なコードを number.html として保存し、ブラウザで開いてください。サーバーなしで、検証、送信された文字列、および数量と重量のJavaScript数値を比較します。この演習では、重量を0~100 kgで0.01 kg単位で定義します。

<!doctype html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>数値の範囲と間隔</title>
  <style>
    body { margin: 24px; font-family: sans-serif; }
    label { display: block; margin: 16px 0 6px; }
    input { width: 12rem; max-width: 100%; box-sizing: border-box; }
    pre { white-space: pre-wrap; overflow-wrap: anywhere; }
  </style>
</head>
<body>
  <h1>数量と重さの入力</h1>
  <form id="demo">
    <label for="quantity">数量(1~10、1個単位)</label>
    <input id="quantity" name="quantity" type="number"
      min="1" max="10" step="1" value="2" required>
    <label for="weight">重さ(0~100kg、0.01kg単位)</label>
    <input id="weight" name="weight" type="number"
      min="0" max="100" step="0.01" value="1.25" required>
    <p><button type="submit">値を確認</button>
      <button type="reset">初期化</button></p>
  </form>
  <pre id="result" aria-live="polite"></pre>
  <script>
    const form = document.querySelector('#demo');
    const quantity = document.querySelector('#quantity');
    const weight = document.querySelector('#weight');
    const result = document.querySelector('#result');
    form.addEventListener('submit', (event) => {
      event.preventDefault();
      result.textContent = JSON.stringify({
        formData: [...new FormData(form).entries()],
        numbers: { quantity: quantity.valueAsNumber, weight: weight.valueAsNumber }
      }, null, 2);
    });
    form.addEventListener('input', () => { result.textContent = ''; });
    form.addEventListener('reset', () => { result.textContent = ''; });
  </script>
</body>
</html>
  1. 初期状態で送信します。 formData (文字列): "2", "1.25"; numbers (数値): 2, 1.25.
  2. 数量を11に設定して最大値検証をトリガーします。検証のステップ用には2.5に設定し、必須検証用には空にします。数量を2に戻します。
  3. 重量 1.23 は送信されますが、1.234 は間隔に合いません。小数点以下の表示桁数の固定は、有効な値の間隔とは異なります。
  4. 数量の step="1" を step="3" に変更してファイルを再度開きます。なぜなら min="1"、初期値 2 は無効で 4 が有効だからです。その後、ステップを 1 に戻します。
  5. リセットは数量を 2 に、重量を 1.25 に戻し、結果をクリアします。

数字のように見える識別子を区別します。

電話番号、郵便番号、会員 ID は、算術処理よりも元の文字列を保持する必要があることがよくあります。先頭のゼロやハイフンが重要になる場合があります。電話の場合は type="tel"、数字のように見える識別子の場合は type="text" inputmode="numeric" を検討してください。inputmode はキーボードのヒントであり、数字のバリデーションルールではありません。

数値入力では、桁数や正規表現パターンを制限するために maxlength や pattern は使用しないでください。サイズではなく CSS で幅を設定してください。ブラウザによって文字入力の挙動、増減矢印、十進区切り表示が異なるため、見た目やブロック挙動に依存しないでください。

JavaScript およびサーバー側で数値を扱う

input.value と通常のフォーム送信値は文字列です。数値には valueAsNumber を使用してください;空の場合や変換できない場合は NaN を返します。Number() で空文字列を変換するとゼロになるため、ゼロとは意味が異なる場合は最初に空の値を区別してください。

ブラウザの検証だけでは値を信頼できるものにはなりません。数値の形式、有限の値かどうか、範囲、およびステップはサーバー側でも検証してください。金額など小数精度が必要な計算では、JavaScriptの二進浮動小数点の誤差を考慮し、最小通貨単位の整数または適切な小数アプローチを使用してください。

MDN の数値入力リファレンスでは、属性とステップ基準のルールについて説明しています。