根本原因是min或max缺失导致value被忽略;必须显式设置min和max为数字,value需为纯数字,low/high/optimum需满足严格大小关系才生效。

为什么写了却看不见进度条
根本不是样式没加,而是 min 或 max 缺失。浏览器不会自动补范围——<meter value="75"></meter> 在 Chrome 里 fallback 成 min="0" max="1",结果 value="75" 被当成 7500% 溢出,直接静默丢弃;Firefox 更干脆,getBoundingClientRect().height 返回 0。
必须显式写全三个核心属性:min、max、value,且都得是纯数字:
-
value不能带单位:value="75%"、value="0.75"全部失效,得写成75或75.0 - 后端返回小数(如
0.72)时,JS 里建议统一处理:Math.round(parseFloat(apiValue) * 100),再用Math.min(Math.max(newValue, min), max)做边界 clamp - 哪怕业务上
min就是 0、max就是 100,也得写出来:min="0" max="100",不能省
和
语义不同,不能互换。用错会导致读屏器误读、无障碍失效,甚至影响 SEO。
- 用
<progress>:只适用于「有起点、单向推进、不可回退」的任务流,比如文件上传、页面加载、表单提交。它只有value和max,没有min,且value必须 ≥ 0 - 用
<meter>:只适用于「静态快照式」的标量测量值,比如磁盘使用率(0–100%)、信用分(300–850)、响应时间(0–500ms)、剩余天数(0–30)。它必须同时有min、max、value,且value可为负(如温度 -5℃ 在 -20℃~40℃ 区间内) - 数值会回退?比如电量从 80% 掉到 75% → 用
<meter>;数值只增不减?比如安装进度 → 用<progress>
low/high/optimum 属性为什么不起作用
它们不是样式开关,而是语义信号,生效条件非常严格,且跨浏览器支持极差。
-
low必须严格大于min(low="0"在min="0"下无效);high必须严格小于max(high="100"在max="100"下不触发“高”状态) -
low和high必须满足min < low < high < max,写反(如low="80" high="30")会导致整个逻辑失效 -
optimum必须落在[min, max]内,可等于边界(如噪音分贝越低越好,就设optimum="min") - Firefox 完全忽略
low/high的视觉反馈;Chrome 和 Safari 对optimum的着色策略不一致(同个值在 Chrome 显黄,在 Safari 可能偏橙) - 别指望靠它们驱动业务逻辑——没有对应事件,颜色变化不可监听,状态判断必须靠 JS 手动计算
怎么让真正可用、可访问
纯 HTML 不够,必须组合基础属性 + 简单 CSS + 显式文本 + ARIA。
立即学习“前端免费学习笔记(深入)”;
- 始终显式写全
min、max、value,内容文本(如<meter ...>73%</meter>)是给不支持该标签的浏览器或读屏器看的,不是装饰 - 自定义样式只能靠伪元素,且前缀不能省:
meter::-webkit-meter-bar、meter::-moz-meter-bar;直接写meter { background: red; }不生效 - 动态更新时,只改
textContent或innerHTML不会重绘,必须用element.setAttribute('value', newValue)或element.value = newValue,并同步更新aria-valuenow - 高频更新(如每 50ms)易卡顿或闪烁,建议加节流;关键状态提示(如“电量不足”)不能只靠 meter 内容文本,得额外加 aria-live 或视觉提示
真正难的不是写对标签,而是想清楚这个值有没有公认的上下界、是否需要传达“偏低/偏高/理想”的隐含判断——没想清这点,加再多 CSS 也救不回语义混乱。



















