step属性仅对type="number"和type="range"生效,定义合法值为min + n×step(n为整数);未设min时基准为0,浮点误差可能导致旧版chrome中step被转为1;小数校验需统一精度或换算为整数处理,动态修改step后须手动规整value并延迟更新。

直接说结论:step 属性本身不拦截输入,只定义合法值集合和校验规则;它只对 type="number" 和 type="range" 生效,写在 type="text" 上完全无效。
为什么 step="0.1" 输入 1.25 会报错?
浏览器提交时执行原生校验,判断逻辑是:当前值是否满足 value === min + n × step(n 为整数)。默认 min 是 0,step="0.1" 的合法值是 0, 0.1, 0.2, ..., 1.2, 1.3 —— 1.25 不在其中,触发 validity.stepMismatch,提示 “Please enter a valid value. The two nearest valid values are 1.2 and 1.3”。
- 没设
min时,基准是 0,不是用户直觉的“从当前值开始” -
min="1"且step="0.3"时,合法值是1.0, 1.3, 1.6, 1.9...,不是1.25, 1.55 - 浮点误差会让
step="0.1"在旧版 Chrome 中被静默转成step="1",导致行为突变
如何让小数输入真正通过校验?
关键不是“允许输”,而是“让值落在步长格点上”。最稳做法是统一小数位并显式对齐:
- 金额类:用“分”代替“元”,
min="0"→min="100",step="1",value="199"表示 1.99 元 - 必须用小数:补零写死精度,
min="0.00"、max="10.00"、step="0.01",避免混用min="0"和step="0.01" - 初始
value必须合规,value="1.05"配step="0.1"会导致浏览器静默修正为1.0或1.1,spinner 可能失灵
动态改 step 后为什么 spinner 不动或跳变?
浏览器不会自动重算合法值集合。旧 value 很可能已非法,拖拽松手或点箭头时会被强制对齐到最近格点,造成跳变或卡顿。
- 别直接赋值
input.step = "0.25",改用input.setAttribute("step", "0.25") - 改完立刻规整
value:input.value = (Math.round(parseFloat(input.value) / 0.25) * 0.25).toFixed(2) - 连续切换 step 时,用
requestAnimationFrame延迟重置value,避免状态残留 - 调用
input.checkValidity()主动检测,必要时input.reportValidity()提示用户
最常被忽略的其实是粘贴、方向键微调、第三方输入法——这些操作完全绕过 step 约束,浏览器只在校验和增减按钮上起作用。真要控精度,得靠 JS 实时截断 + 后端兜底。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











