step 属性通过数学条件 (value − min) % step === 0 判定合法值,仅对 type="number" 有效;type="date" 等忽略 step,datetime-local 的 step 必须为整数且仅限秒级;手动输入不受限,需 js 配合校验与修复。

step 属性决定哪些值算“合法”,不只是上下箭头的增减量
设 step="0.1" 后,用户输入 1.05 会触发 stepMismatch 错误——不是因为“输错了”,而是它不满足 (value − min) % step === 0 这个数学条件。浏览器在 checkValidity() 或表单提交时会拦住它,但不会自动修正或四舍五入。
常见现象:输入框看着有值,input.checkValidity() 却返回 false;点击提交没反应,控制台也没报错——大概率是被 step 静默拦截了。
-
step必须写成字符串(如"0.1"),避免 JS 浮点计算误差影响解析 - 想允许任意小数(比如价格录入支持
19.995),必须显式写step="any",不能省略或写step="0.01" - 整数场景下,
step="1"比不写更明确,能防止某些旧浏览器 fallback 到默认行为
min/max 和 step 联合生效时,合法值是离散的,不是连续区间
min 和 max 定义的是数学边界,但最终可提交的值必须同时落在 [min, max] 内,且是 min + n × step 的形式(n 为 ≥0 整数)。
例如:<input type="number" min="1" max="5" step="2">,合法值只有 1、3、5;而 min="0.5" max="2.5" step="0.7" 的合法值是 0.5、1.2、1.9(2.6 超出 max,直接排除)。
- 若
min="1"但step="0.3",首个合法值是1.2(≥1 的最小0.3倍数),1本身不合法 -
max是硬性上限,不会做向下取整或截断;超出即 invalid,不自动修正 - 移动端 Safari 对该逻辑支持稳定,但部分 Android WebView 会忽略
step,需 JS 补验
type="number" 的 step 对日期类 input 几乎无效
step 只对 type="number" 有完整语义作用;对 type="date"、type="month"、type="week",所有浏览器都忽略 step 值——上下箭头永远按天/月/周移动,设 step="7" 不会跳周,设 step="30" 也不会跳月。
唯一例外是 type="datetime-local":此时 step 表示秒级步进,且**必须为整数**(如 step="60" 表示 1 分钟),小数会被截断为整数(step="30.5" → 实际按 30 秒处理)。
- iOS 上
datetime-local常绕过step,直接调用系统原生选择器,无法控制步进精度 - 不要试图用
step限制日期粒度;改用type="date"+ JS 校验日期是否为某周期倍数(如每周一)更可靠
手动输入不受 step 约束,但校验和修复得自己来
用户仍可输入任意数字(如 step="5" 时输 7),step 只在点击箭头、方向键微调、或调用 input.stepUp()/input.stepDown() 时起作用。提交前浏览器会标记为 :invalid,但不会阻止输入或自动修正。
要真正“限制”,得配合 JS:
- 监听
input事件,用parseFloat(input.value)解析后判断是否满足(val - min) % step === 0 - 发现非法值时,可主动设回最近合法值(如向上/向下取整到最近
step倍数) - 用
input.validity.stepMismatch判断是否因step失败,比正则或字符串匹配更准确
最易被忽略的一点:即使你写了完整的 min、max、step,只要没监听 change 或 input 做二次校验,用户就可能带着非法值进入后端——而服务端若没做等价校验,数据就会出错。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











