step 属性仅对 type="number" 等特定类型生效,不控制输入合法性,仅参与原生校验与增减交互;type="text" 中无效,type="date"/"month" 被浏览器忽略,浮点精度会导致 stepmismatch,需配合 min/value 严格满足数学约束,并始终服务端校验。

step 属性本身不“控制”输入值的合法性,它只参与浏览器原生校验逻辑和交互增减行为——设了不一定拦得住非法输入,但没设清楚就大概率出错。
step 只对特定 type 生效,type="text" 上写 step 完全无效
常见错误是:<input type="text" step="0.01"> 看似想限制小数位,实际浏览器解析该属性但完全忽略:没有上下箭头、不能用方向键增减、checkValidity() 不触发 stepMismatch。必须搭配 type="number"(或 range、datetime-local 等)才起作用。
正确写法示例:
<input type="number" step="0.01" min="0" max="100">
-
type="date"和type="month"虽在规范中列支持step,但所有主流浏览器均忽略它——step="7"不会让日期跳周,step="3"也不会让月份跳着选 -
type="datetime-local"支持step,但值必须是整数(单位为秒),如step="60"表示 1 分钟步进;step="0.5"会被截断为0
step="0.1" 输入 0.3 却校验失败?不是 bug,是浮点精度在作祟
浏览器内部用 (value - min) % step === 0 判断合法性,而 0.1 在 IEEE 754 中无法精确表示,导致 0.1 + 0.1 + 0.1 !== 0.3。用户手输 "0.3",浏览器生成的合法序列却是 0、0.10000000000000002、0.20000000000000004……二者不匹配,validity.stepMismatch 就为 true。
规避方式:
- 金额类场景统一用“分”:
min="100"、step="1"、value="199"表示 1.99 元 - 必须用小数时,显式补零:
min="0.00"、max="10.00"、step="0.01",避免min="0"和step="0.01"混用 - 别依赖
parseFloat(input.value) + 0.1计算,改用原生input.stepUp(1),它严格按当前step执行,不引入 JS 浮点误差
value 初始值不匹配 min + n × step,控件会卡住或静默修正
step 不是独立开关,它和 min、value 构成数学约束:value 必须满足 value === min + n × step(n 为整数)。否则 Chrome 可能静默把 value="1.0" 改成 1.2,或让上下箭头失灵。
安全写法:
-
min="0.0"、step="0.1"→value只能是"0.0"、"0.1"、"0.2"… 之一 - 动态改
step后必须重置value:input.value = (Math.round(parseFloat(input.value) / newStep) * newStep).toFixed(2) - 设
step="any"并不等于“关闭校验”,只是禁用步长对齐逻辑:上下箭头退化为 ±1 整数增减,手动输入任意小数(如"1.23456789")也不会触发stepMismatch
真正麻烦的从来不是怎么写 step,而是用户粘贴、拖拽滚动条、用第三方输入法——这些行为完全绕过 step 约束。它只管受控增减,不管自由输入;服务端永远要重做校验,不能信前端 checkValidity() 的结果。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











