合法值从min开始而非0,判断依据是(value-min)%step≈0;max仅截断上限。如min="1" step="2"时合法值为1,3,5,7,9,非2,4,6,8,10。

step 和 max 一起用时,合法值从 min 开始算,不是从 0
浏览器判断一个 value 是否合法,依据是 (value - min) % step ≈ 0(浮点安全比较),而不是 “value 必须能被 step 整除”。max 只负责截断上限,不参与起点计算。
常见错误写法:<input type="number" min="1" max="10" step="2"> → 合法值是 1, 3, 5, 7, 9,不是你期待的 2, 4, 6, 8, 10。因为起点是 min="1",不是 0 或 2。
正确对齐方式:
- 若要支持偶数,设
min="0" step="2"或min="2" step="2" - 若
min来自配置无法改,JS 校验必须用Math.abs((val - min) % step) ,不能直接写 <code>val % step === 0 - Chrome 失焦时会自动把非法值(如
value="7"在min="2" step="3"下)修正为最近合法值(8);Safari 可能静默保留,导致提交失败
max 不等于“显示到最大”,它会砍掉超出的步进点
max 是硬边界,不是提示。即使数学上 min + n × step 算出来刚好等于 max,也必须满足 ≤ max 才被接受。
立即学习“前端免费学习笔记(深入)”;
例如:<input type="number" min="0" max="10" step="3">,合法序列是 0, 3, 6, 9 —— 12 超了,直接丢弃,不会出现 10。
更隐蔽的问题:
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- 当
min + n × step无限逼近max却永远不等于它(比如min="0" max="1" step="0.33"),不同浏览器生成的合法值列表长度可能不同,甚至触发渲染卡顿 - 避免
max="100000" step="0.01"这类组合,改用整数缩放:min="0" max="10000000" step="1",JS 层除以100显示 - 调试可用:
Array.from({length: 20}, (_, i) => min + i * step).filter(x => x 查看实际合法点
type="number" 和 type="range" 对 max+step 的响应方式不同
type="range" 的滑块视觉上可以平滑拖动,但最终取值一定落在 min 到 max 之间且符合 step 对齐的离散点上;type="number" 则只在校验环节(提交、失焦、调用 checkValidity())才强制匹配,输入过程中用户仍可键入任意数字。
这意味着:同一个 min="0" max="5" step="0.5",在 range 中你拖不到 3.3;在 number 中你可以输 3.3,但提交时会报错 stepMismatch。
移动端尤其要注意:
- 软键盘可能只显示数字和小数点,但不阻止用户粘贴非法内容(如
"3.333") - 表单提交前务必调用
input.checkValidity(),比等用户点提交更快暴露validity.rangeOverflow或stepMismatch -
type="range"需配合<output></output>实时反馈当前值,否则用户看不到数值变化
step="any" 会彻底关闭步长校验
显式写 step="any" 表示完全绕过步长逻辑,允许任意数字(包括小数、科学计数法如 1e2)。此时 step="1" 的整数意图彻底失效。
注意:
-
step默认值是"1",不是"any" - 只有显式写
step="any"才会关闭校验 - 若想支持小数但又限制精度(如只允许
0.5倍数),应写step="0.5",而非"any" -
step="any"下,min/max依然生效,但不再参与步长对齐校验
真正需要动态或非线性步长(比如小于 10 时步长为 1,大于等于 10 时步长为 5),原生 step 无能为力,必须靠 JS 拦截 input 事件做实时修正 —— 这是容易被忽略的复杂点。


















