合法值必须满足 value === min + n × step(n 为整数),2.05 不在 min="0"、step="0.1" 的序列中,触发 validity.stepMismatch;浮点精度问题导致旧版 Chrome 可能将 step="0.1" 误作 step="1";应统一小数位数如 min="0.00"、step="0.01",金额类建议换算单位规避误差。

step="0.1" 为什么输入 2.05 就报错
这不是浏览器 bug,是 step 的数学约束在起作用:合法值必须满足 value === min + n × step(n 为整数)。设了 min="0"、step="0.1",合法值就是 0.0、0.1、0.2…,而 2.05 不在该序列中,提交时触发 validity.stepMismatch。
更隐蔽的问题是浮点精度:0.1 在二进制中无法精确表示,旧版 Chrome 曾静默把 step="0.1" 当作 step="1" 处理。所以别依赖字符串写法“看起来像小数”,得靠结构对齐。
- 显式补零:写
min="0.00"、max="10.00"、step="0.01",三者小数位数一致 - 避免混用:
min="0"+step="0.01"容易被部分浏览器降级为step="1" - 验证是否生效:用键盘方向键测试,每次应严格跳
step值,跳得不对就先查value是否合规
type="number" 和 type="range" 的 step 行为差异
step 在两种类型下都生效,但作用方式不同:type="number" 约束输入值、箭头增减和表单校验;type="range" 只影响拖动松手瞬间的“停靠点”和方向键微调,不控制滑块渲染精度——哪怕设 step="0.001",用户也感知不到像素级变化。
-
type="number":支持手动输入、粘贴、上下箭头,全部受step校验(提交前报错) -
type="range":拖动时松手自动对齐到最近合法值(如min="0"、step="0.25",拖到 1.28 会跳到 1.25) - 两者都不拦截粘贴行为:用户粘贴
"3.1415926",step="0.1"不会阻止,只在校验时失败
动态修改 step 后 value 卡住或跳变
直接赋值 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()提示用户
真正能落地的十进制步长方案
别硬扛浮点误差。金额类一律换算单位:min="100"(1.00 元)、step="1"(1 分)、value="199"(1.99 元),显示时再除以 100。这是最稳的。
- 非金额场景必须用小数:统一写满两位,
min="0.00"、max="100.00"、step="0.01" - ± 按钮逻辑必须用原生方法:
input.stepUp(1)和input.stepDown(1),不走parseFloat(val) + 0.01这类 JS 浮点运算 - 键盘微调(Shift+↑)由浏览器自动支持,无需额外监听,但前提是
min/step量级匹配(max - min ≤ 10时step="0.01"更可靠)
最麻烦的从来不是写 step,而是用户粘贴、拖拽滚动条、第三方输入法——这些行为完全绕过所有原生约束,step 根本不起作用。



















