LEARNING OBJECTIVES ⌵
- Understand the mathematical mechanics of
min,max, andstepattributes across numerical and temporal inputs. - Map range attributes directly to the
validity.rangeUnderflow,validity.rangeOverflow, andvalidity.stepMismatchAPI flags. - Master the step-base algorithm to understand why
min="3" step="5"permits8and13, but rejects10. - Implement
step="any"to permit arbitrary floating-point numbers without triggering step mismatch errors. - Enforce business boundaries on temporal inputs (
date,time,datetime-local).
📖 The Mental Model & Story (Intuitive Foundation)
Imagine stepping across a river using a series of evenly spaced stones, alongside a strict bridge weight capacity:
+-----------------------------------------------------------------------------+
| THE STEPPING STONES ANALOGY |
+-----------------------------------------------------------------------------+
| |
| River Bank (min = 3) River Bank (max = 18)
| │ │ |
| ▼ ▼ |
| [ 3 ] ──────► [ 8 ] ──────► [ 13 ] ──────► [ 18 ] ───► (Bridge End) |
| ▲ ▲ |
| │ │ |
| Step Size (+5) │ |
| │ |
| Attempt: 10 |
| (Splashes in Water! stepMismatch = true) |
| |
| Attempt: 1 (Too low! rangeUnderflow) Attempt: 25 (Too high! rangeOverflow)
| |
+-----------------------------------------------------------------------------+
- The Minimum Boundary (
min): You cannot step behind the starting bank. If you try to stand at position1, you fall backward (rangeUnderflow). - The Maximum Boundary (
max): The path ends at position18. Trying to step to position25exceeds the limit (rangeOverflow). - The Step Interval (
step): The stones are placed at intervals of5starting from position3. You can only land safely on3,8,13, and18. If you try to step on position10, you step into empty water (stepMismatch).
In HTML5, inputs of type number, range, date, time, and datetime-local use this exact stepping stone algorithm.
Technical Deep Dive & Specifications
2.1 The Step-Base Calculation Algorithm
According to the WHATWG HTML Standard (§ 4.10.5.3.8 "The step attribute"), an input value is valid with respect to step if and only if:
$$\text{Value is a valid step} \iff (\text{value} - \text{stepBase}) \pmod{\text{step}} = 0$$
What is stepBase?
- If the element has a
minattribute, $\text{stepBase} = \text{min}$. - If the element has no
minattribute, but has avalueattribute default, $\text{stepBase} = \text{defaultValue}$. - Otherwise, $\text{stepBase} = \text{defaultStepBase}$ (which is
0for numbers).
Example: <input type="number" min="10" max="50" step="10">
• Valid values: 10, 20, 30, 40, 50
• Invalid values: 15 (stepMismatch), 5 (rangeUnderflow), 60 (rangeOverflow)
Example: <input type="number" min="3" max="23" step="5">
• Valid values: 3, 8, 13, 18, 23 (Notice: 5, 10, 15 are INVALID because base is 3!)
2.2 The step="any" Escape Hatch
By default, <input type="number"> has an implicit step="1". If a user enters 4.25, the browser rejects the input with a stepMismatch error!
To allow arbitrary decimal values (such as currency fractions, latitude/longitude, or physics measurements) while still retaining min and max constraints, use step="any":
<!-- Allows ANY floating-point number between 0.0 and 100.0 -->
<input type="number" min="0" max="100" step="any">
2.3 Constraint Validation Flags
The Constraint Validation API exposes three specific boolean flags on element.validity for range checking:
+----------------------------------------------------------------------------------------------------+
| RANGE VALIDITY FLAGS MATRIX |
+----------------------------------------------------------------------------------------------------+
FLAG TRIGGER CONDITION HTML ATTRIBUTE
───────────────────────────────────────────────────────────────────────────────────────────────────
validity.rangeUnderflow Parsed value is strictly less than min min="value"
validity.rangeOverflow Parsed value is strictly greater than max max="value"
validity.stepMismatch (value - stepBase) is not a multiple of step step="value"
2.4 Temporal Input Boundaries (date, time, datetime-local)
Range validation is not limited to integers and floats. Temporal inputs use ISO 8601 strings:
| Input Type | Format Example | step Unit |
Example Usage |
|---|---|---|---|
<input type="date"> |
YYYY-MM-DD |
Days (1 = 1 day) |
min="2026-01-01" max="2026-12-31" |
<input type="time"> |
HH:MM or HH:MM:SS |
Seconds (900 = 15 mins) |
min="09:00" max="17:00" step="900" |
<input type="month"> |
YYYY-MM |
Months (1 = 1 month) |
min="2026-01" max="2026-12" |
<input type="datetime-local"> |
YYYY-MM-DDTHH:MM |
Seconds (3600 = 1 hour) |
min="2026-08-01T00:00" |
💻 Interactive Code Playground
Starter Code
The following financial transaction dashboard demonstrates min, max, and step across currency amounts, transaction dates, and appointment booking time slots.
Line-by-Line Code Breakdown
- Lines 82-90 (
min="10.00" max="10000.00" step="0.01"): Restricts numeric input to financial amounts. Entering9.99triggersrangeUnderflow, entering10000.01triggersrangeOverflow, and entering50.123triggersstepMismatch. - Lines 97-105 (
<input type="date" min="2026-07-01" max="2026-12-31">): Enforces date boundaries using ISO-8601 strings (YYYY-MM-DD). - Lines 111-119 (
<input type="time" min="09:00" max="17:00" step="900">): Sets a time window between 9 AM and 5 PM.step="900"enforces 15-minute granularity (900 seconds). Entering09:07triggersstepMismatch. - Lines 141-150 (
v.rangeUnderflow,v.rangeOverflow,v.stepMismatch): Inspects all three individual flags from thevalidityobject.
Expected Browser Render Output
+---------------------------------------------------------------+
| Treasury Transfer Portal |
| Enforcing strict numerical and temporal bounds. |
| |
| Transfer Amount ($10.00 – $10,000.00) * |
| [ 500.00 ] |
| min="10.00" max="10000.00" step="0.01" |
| |
| Execution Date (2026-07-01 to 2026-12-31) * |
| [ 2026-08-21 ] |
| min="2026-07-01" max="2026-12-31" step="1" (daily) |
| |
| Settlement Time Slot (09:00 – 17:00, 15m intervals) * |
| [ 09:15 ] |
| min="09:00" max="17:00" step="900" (900s = 15 minutes) |
| |
| [ Execute Wire Transfer ] |
| |
| [AMOUNT] Real-time Validity: |
| • Value: "500.00" |
| • rangeUnderflow: false |
| • rangeOverflow: false |
| • stepMismatch: false |
| • valid: true |
+---------------------------------------------------------------+🏋️ Hands-On Exercise
🎯 The Challenge: Real Estate Auction Bidding Terminal
Scenario: You are building an auction bidding module for real estate properties.
- Starting Price (
min): $250,000 - Maximum Reserve Ceiling (
max): $2,000,000 - Bid Increment (
step): Bids must increase in exact increments of $5,000. - Auction Slot Time: Bidding is only open between
10:00and16:00, in increments of 30 minutes (1800seconds).
Instructions:
- Create a form with a number input for
bidAmountand a time input forbiddingTime. - Configure
min,max, andstepon both inputs according to the rules above. - Test that entering
$255,000is valid, but$252,500triggersstepMismatch. - Test that
10:30is valid, but10:15triggersstepMismatch.
🏁 Starter Code Sandbox
⚠️ Common Pitfalls
- Default
step="1"on Numbers: Leaving off thestepattribute when asking for decimal numbers (e.g.$19.99or GPS coordinates37.7749). The browser defaultsstepto1on numbers, causing valid decimals to be rejected withstepMismatch. Always specifystep="0.01"orstep="any". - Forgetting Step-Base Offsets: Writing
<input type="number" min="1" step="2">and expecting even numbers (2, 4, 6) to be valid. The step base is1, so only odd numbers (1, 3, 5, 7) are valid! - Time Inputs and Seconds Precision: The default
stepfor<input type="time">is60(one minute). If your users need to specify seconds (10:15:30), you must specifystep="1".
💡 Pro Tips
- Dynamic Date Min/Max Boundaries: In booking applications, restrict checkout dates to future days dynamically via JavaScript:
const today = new Date().toISOString().split('T')[0]; document.getElementById('checkin').min = today; - Use
step="any"for Unrestricted Floats: When building forms for geographical coordinates (latitude/longitude) or scientific measurements,step="any"eliminates step checks completely while keepingminandmaxconstraints active.
📌 Key Takeaways
rangeUnderflow: Occurs when the input value is strictly less than theminattribute.rangeOverflow: Occurs when the input value is strictly greater than themaxattribute.stepMismatch: Occurs when $(value - stepBase) \pmod{step} \neq 0$.- Step Base: Defaults to
minif defined, otherwise0for numbers. Step calculations are always relative to the base. step="any": Allows any floating-point number without triggeringstepMismatch.- Temporal Steps: For
<input type="time">, step values are measured in seconds (900= 15 minutes,1= 1 second). - --