min / max / step
min、max 和 step 属性用于约束数值型、日期型和范围型输入控件的值。min 设置最小值,max 设置最大值,step 设置合法值的步进间隔。这三个属性协同工作,为数值和日期输入提供了精确的范围控制。
前置知识
阅读本节前,建议先了解:pattern 正则验证
基础概念
属性说明
| 属性 | 说明 | 适用类型 |
|---|---|---|
min | 允许的最小值 | number, range, date, time, datetime-local, month, week |
max | 允许的最大值 | 同上 |
step | 合法值的步进间隔 | 同上 |
验证逻辑
当用户提交表单时,浏览器会检查:
- 值是否 >=
min(如果设置了 min) - 值是否 <=
max(如果设置了 max) - 值是否满足
step的步进规则
语法
number 数值范围
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>min/max/step 数值</title>
</head>
<body>
<h2>数量选择</h2>
<form>
<label for="quantity">数量:</label>
<input
type="number"
id="quantity"
name="quantity"
min="1"
max="99"
step="1"
value="1"
required
>
<button type="submit">提交</button>
</form>
</body>
</html>date 日期范围
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>min/max 日期范围</title>
</head>
<body>
<h2>预约日期</h2>
<form>
<label for="appointment-date">预约日期:</label>
<input
type="date"
id="appointment-date"
name="appointment_date"
min="2025-07-15"
max="2025-12-31"
required
>
<button type="submit">提交</button>
</form>
</body>
</html>time 时间范围
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>min/max 时间范围</title>
</head>
<body>
<h2>工作时间</h2>
<form>
<label for="work-time">选择时间:</label>
<input
type="time"
id="work-time"
name="work_time"
min="09:00"
max="18:00"
step="1800"
required
>
<button type="submit">提交</button>
</form>
</body>
</html>详细说明
step 步进规则
step 属性定义了合法值的间隔。浏览器验证 value 是否满足 (value - min) % step === 0(允许浮点误差)。
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>step 步进示例</title>
</head>
<body>
<h2>step 步进控制</h2>
<form>
<div>
<label for="int-step">整数步进(step=1):</label>
<!-- 合法值:0, 1, 2, 3, 4, 5 -->
<input type="number" id="int-step" min="0" max="5" step="1" value="0">
</div>
<div>
<label for="float-step">小数步进(step=0.5):</label>
<!-- 合法值:0, 0.5, 1, 1.5, 2, 2.5, 3 -->
<input type="number" id="float-step" min="0" max="3" step="0.5" value="0">
</div>
<div>
<label for="five-step">步进为5(step=5):</label>
<!-- 合法值:0, 5, 10, 15, 20, 25, 30 -->
<input type="number" id="five-step" min="0" max="30" step="5" value="0">
</div>
<div>
<label for="any-step">任意值(step=any):</label>
<!-- 任何值都合法 -->
<input type="number" id="any-step" min="0" max="100" step="any">
</div>
</form>
</body>
</html>| step 值 | 含义 | 示例合法值(min=0, max=10) |
|---|---|---|
1(默认) | 整数步进 | 0, 1, 2, 3... |
0.5 | 半步进 | 0, 0.5, 1, 1.5... |
5 | 每 5 个 | 0, 5, 10 |
0.01 | 精确到分 | 0.00, 0.01, 0.02... |
any | 不限制 | 任意值 |
range 滑块的 min/max/step
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>range min/max/step</title>
<style>
body { font-family: sans-serif; max-width: 600px; margin: 40px auto; }
.slider-group { margin-bottom: 16px; }
label { display: block; margin-bottom: 4px; font-weight: 600; }
input[type="range"] { width: 300px; }
</style>
</head>
<body>
<h2>滑块范围控制</h2>
<form>
<div class="slider-group">
<label for="volume">音量(0-100,步进5):</label>
<input type="range" id="volume" min="0" max="100" step="5" value="50">
<output for="volume">50</output>
</div>
<div class="slider-group">
<label for="temperature">温度(16-32,步进0.5):</label>
<input type="range" id="temperature" min="16" max="32" step="0.5" value="24">
<output for="temperature">24</output>
</div>
<div class="slider-group">
<label for="zoom">缩放(1-10,步进0.1):</label>
<input type="range" id="zoom" min="1" max="10" step="0.1" value="1">
<output for="zoom">1</output>
</div>
</form>
<script>
document.querySelectorAll('form').forEach(form => {
form.addEventListener('input', function () {
this.querySelectorAll('input[type="range"]').forEach(range => {
range.nextElementSibling.value = range.value;
});
});
});
</script>
</body>
</html>:out-of-range 和 :in-range 伪类
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>range 伪类</title>
<style>
body { font-family: sans-serif; max-width: 600px; margin: 40px auto; }
input {
padding: 8px 12px;
border: 2px solid #ddd;
border-radius: 6px;
font-size: 16px;
}
/* 在范围内 */
input:in-range {
border-color: #27ae60;
}
/* 超出范围 */
input:out-of-range {
border-color: #e74c3c;
}
</style>
</head>
<body>
<h2>范围伪类</h2>
<form>
<label for="age">年龄(18-65):</label>
<input type="number" id="age" name="age" min="18" max="65" value="25">
<p>输入超出 18-65 范围的值,边框会变红。</p>
</form>
</body>
</html>实战示例
商品数量选择器
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>商品数量</title>
<style>
body { font-family: sans-serif; max-width: 600px; margin: 40px auto; }
.qty-control {
display: flex;
align-items: center;
gap: 12px;
}
.qty-control button {
width: 36px;
height: 36px;
border: 2px solid #ddd;
border-radius: 6px;
background: #fff;
font-size: 18px;
cursor: pointer;
}
.qty-control button:hover { background: #f0f0f0; }
.qty-control input {
width: 80px;
text-align: center;
font-size: 18px;
padding: 6px;
border: 2px solid #ddd;
border-radius: 6px;
}
.price { font-size: 20px; color: #e74c3c; font-weight: bold; margin-top: 8px; }
</style>
</head>
<body>
<h2>商品数量</h2>
<form>
<div class="qty-control">
<button type="button" onclick="adjustQty(-1)">-</button>
<input type="number" id="qty" name="quantity" min="1" max="99" step="1" value="1"
oninput="updatePrice()">
<button type="button" onclick="adjustQty(1)">+</button>
</div>
<p>单价:¥99.00</p>
<p class="price">总价:<span id="total-price">¥99.00</span></p>
</form>
<script>
const qtyInput = document.getElementById('qty');
const price = 99;
function adjustQty(delta) {
let val = parseInt(qtyInput.value) || 1;
val = Math.min(Math.max(val + delta, parseInt(qtyInput.min)), parseInt(qtyInput.max));
qtyInput.value = val;
updatePrice();
}
function updatePrice() {
const qty = parseInt(qtyInput.value) || 1;
document.getElementById('total-price').textContent = `¥${(qty * price).toFixed(2)}`;
}
</script>
</body>
</html>注意事项
浮点数精度问题
step 为小数时可能出现浮点精度问题:
javascript
// 浏览器允许一定的浮点误差
// step=0.1, min=0, 输入 0.3 可能被认为是合法的step=any 不限制步进
step="any" 表示不限制步进,但 min 和 max 的范围约束仍然有效。
range 控件永远在范围内
<input type="range"> 的值始终在 min/max 范围内(浏览器自动钳制),:out-of-range 对 range 控件无意义。
min > max 的情况
如果 min 大于 max,浏览器会忽略 min,使用 max 作为上界。
最佳实践
- 合理设置范围:min/max 应反映业务逻辑的实际约束
- 选择合适步进:步进值应根据业务精度需求设置
- 使用 number 输入步进器:
type="number"提供上下箭头控制步进 - range 配合 output:滑块始终显示当前值
- 日期时间范围联动:起止日期/时间应联动更新 min/max
- 提供 :in-range/:out-of-range 样式:帮助用户感知范围约束
下一节