step属性仅定义合法值集合和浏览器内置操作的增量单位,不拦截非法输入;必须配合min/max限定范围,且value初始值须满足value=min+n×step,否则浏览器静默修正导致交互异常。

step 属性本身不“控制数值变化”,它只定义合法值集合和浏览器内置操作(如箭头点击、滚轮、滑块停靠)的增量单位。单写 step="0.1" 而不配 min 和 max,几乎等于没设约束。
为什么设了 step 还能输非法值?
浏览器只在校验时(提交、checkValidity())检查 value === min + n × step(n 为整数),并不拦截键盘输入或粘贴。用户输 2.05 在 step="0.1" 下完全可行,直到点提交才报 validity.stepMismatch。
- 别依赖它做实时过滤——
input事件里仍要手动截断或校验 - 移动端软键盘可能根本不提供小数点(尤其 iOS number 键盘),
step="0.1"可能让用户根本输不了小数 - 粘贴
"1.234"后不触发校验,除非主动调用checkValidity()
step 必须和 min/max 配合才有效
合法值由三者共同生成:从 min 开始,每次加 step,直到超过 max。单独写 step="5",min 默认是 0,max 默认是 100,结果只能取 0、5、10…100 —— 很可能不是你想要的范围。
-
min="10"+step="5"→ 合法值:10、15、20… -
min="0.1"+step="0.2"→ 合法值:0.1、0.3、0.5…(注意不是 0.2、0.4) -
min="1"+step="0.3"→ 第一个合法值是 1,但 1.3 是下一个;部分浏览器在箭头调节时会跳到 1.2(最近对齐值),行为不一致
金额等敏感场景慎用浮点 step
step="0.01" 看似合理,但二进制浮点误差会让某些值(如 0.3)被判定为非法。Chrome 旧版本甚至会把 step="0.1" 静默转成 step="1"。
- 推荐方案:统一用整数单位,如金额存“分”——
min="0"、step="1"、value="199"表示 1.99 元 - 若必须用小数,显式对齐位数:
min="0.00"、max="999.99"、step="0.01" - JS 动态设置 value 前,务必先对齐:
Math.round(parseFloat(val) / 0.01) * 0.01
动态改 step 后 spinner 失灵怎么办?
直接赋值 input.step = "0.25" 不可靠,浏览器不会重算合法值集合,旧 value 很可能已越界,导致箭头点不动、滑块拖拽卡顿。
- 用
input.setAttribute("step", "0.25")更稳定 - 立即重置
value:先规整再写入,例如input.value = (Math.round(parseFloat(input.value) / 0.25) * 0.25).toFixed(2) - 连续切换时加
requestAnimationFrame延迟重置,避免状态残留 - 改完调用
input.checkValidity(),必要时input.reportValidity()主动提示
最常被忽略的一点:初始 value 必须与 min 和 step 对齐。写 value="1.05" 却配 min="0"、step="0.1",Chrome 可能静默改成 1.0 或 1.1,而 DOM 上看不出变化——这会导致后续所有交互异常。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











