The HTML min attribute
The HTML min attribute gives an input its lowest allowed value, such as min="1" or min="09:00". It's also where steps start, so min="0.5" with the default step of 1 accepts 1.5 and rejects 2. Any date before min="2026-11-02" makes a date field report rangeUnderflow.
Overview
The HTML min attribute is an input's lower limit and the starting point of its steps. Number, range and the date and time <input> types take it, and <meter> does too. In a form field, a lower value sets validity.rangeUnderflow, except on a slider or inside an overnight time range.
The step attribute counts from min, a starting point called the step base. With min="09:00" and step="1800", time slots fall on the hour and half hour, and min="09:15" moves them 15 minutes later. Without a usable min, steps count from the value attribute, if there is one.
A range slider's scale starts at 0 when min is missing or unreadable. With no value set, the thumb sits halfway between min and max, so min="20" and the default max of 100 start it at 60. A slider has no underflow to report, because any lower value jumps to min.
With step="7" on a date input, a Monday min such as 2026-11-02 makes every valid day a Monday. Each date and time type has its own format, such as 2026-11-02T09:00 for datetime-local and 2026-W45 for week, though desktop Firefox and Safari have no week or month input.
A time input is the one type where min may come after max. With min="22:00" and max="06:00", the range starts at 22:00 and runs past midnight, so 03:00 passes. Noon falls outside it, and the field reports rangeUnderflow and rangeOverflow together.
Syntax
<label for="checkin">Check-in date</label>
<input type="date" id="checkin" name="checkin" min="2026-11-02">
Values
| Value |
|---|
| A number, or a date or time string in the input type's format. |
Example
<p><label for="day">Lesson date (today or later)</label><br>
<input type="date" id="day" name="day"></p>
<p><label for="start">Start time (from 09:00, every 30 min)</label><br>
<input type="time" id="start" name="start" min="09:00" step="1800" value="08:30"></p>
<p id="msg" role="status"></p>
<p>Try 08:30, 10:15 and 10:30, then pick today or a later date.</p>
<script>
const day = document.getElementById('day');
const start = document.getElementById('start');
const iso = d => d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2, '0') + '-' + String(d.getDate()).padStart(2, '0');
const now = new Date();
day.min = iso(now);
now.setDate(now.getDate() - 1);
day.value = iso(now);
function check() {
const notes = [];
for (const field of [day, start]) {
const name = field.labels[0].textContent.split(' (')[0];
if (!field.value) notes.push(name + ' is empty, so min has nothing to check.');
else if (field.validity.rangeUnderflow) notes.push(name + ' is before ' + field.min + '.');
else if (field.validity.stepMismatch) notes.push(name + ' is off the 30-minute steps from ' + field.min + '.');
}
document.getElementById('msg').textContent = notes.join(' ') || 'Both fields pass their min.';
}
day.addEventListener('input', check);
start.addEventListener('input', check);
check();
</script>
Best practices
- Update
minthrough its property when it depends on another field, as incheckout.min = checkin.value. The browser checks the current value against the new limit right away. - Branch on
validity.rangeUnderflowwhen you write your own error text. The same field can also fail with stepMismatch or valueMissing, and each needs different wording. - Add
min="0"to prices andmin="1"to quantities. A number input has no minimum of its own, so without one a value such as -5 passes. - Set min on a <meter> whose scale doesn't start at 0, such as a thermometer from -20 to 40. Without it, the gauge starts at 0 and shows any lower value as 0. A <progress> bar has no min and always counts up from 0.
Accessibility
The min of a number or range input reaches assistive technology as the control's minimum value. It maps to aria-valuemin, and Chrome reports it that way for spin buttons and sliders. An element with min must not also carry aria-valuemin, according to ARIA in HTML.























