HTML 的 `<meter>` 和 `<progress>` 有什么区别?怎么用

域名注册
域名注册 正式会员超兽战士 👑年卡会员
发布于 2026-10-08 18:18 ·1 浏览 ·0 回复

<progress> 描述的是"一个任务完成了多少",会随时间走向终点,还能表达"不确定进度";<meter> 描述的是"一个已知范围内的当前测量值",比如磁盘占用率、考试分数、评分,它没有终点概念。判断标准只有一条:**数值会随着任务推进自动趋向最大值并且有完成态,就用 <progress>;数值是一个静态刻度的读数、还可能带"哪个区间算好"的语义,就用 <meter>。**

<progress> 和 <meter> 有什么区别?

核心区别有三点,记住这三条就不会用错:

  1. 是否有不确定态。 <progress> 省略 value 属性时进入"不确定进度"状态(浏览器显示来回滚动的动画条),适合"正在加载、还不知道总量"的场景。<meter> 没有不确定态,按 HTML 规范它的 value 是必需属性。
  2. 语义方向不同。 <progress> 的语义是"任务 X% 完成",终点固定是 max;<meter> 的语义是"当前读数在某个刻度尺上的位置",没有"完成"这回事。
  3. 是否表达好坏。 <meter> 有 low、high、optimum 三个属性用来标记"哪个区间是好的",<progress> 没有这套概念,任何进度值都不代表好坏。

在无障碍树上两者映射的角色也不同:<progress> 对应 progressbar,<meter> 对应 meter,屏幕阅读器读出来的提示语完全不一样。

<progress> 怎么用?

<progress> 只有两个属性:max 默认值是 1,value 省略即不确定态。value 超出 [0, max] 时会被截断到边界,不会报错。

<!-- 确定进度:已下载 70 / 200 -->
<progress max="200" value="70">已下载 70 / 200</progress>

<!-- 不确定进度:不知道总量 -->
<progress>正在加载…</progress>

<!-- 完成态:value 等于 max -->
<progress max="100" value="100">已完成</progress>

开始标签和结束标签之间的文字是降级内容,不支持该元素的旧浏览器会显示这段文字,建议照写一遍可读信息。

用 JS 更新进度只需改 value:

const p = document.querySelector('progress');
p.max = total;
p.value = loaded;      // 到达 total 即为完成
p.removeAttribute('value'); // 切回不确定态

注意: 不要用 <progress> 表示磁盘占用率或评分——那类数值永远不会"完成",语义是错的。

<meter> 怎么用?low、high、optimum 分别是什么?

<meter> 的默认刻度是 min="0"、max="1",value 必填;value 小于 min 或大于 max 时会被夹到区间边界。low 的默认值等于 min,high 的默认值等于 max,optimum 的默认值是 min 和 max 的中点。

<!-- 磁盘占用 68%,越少越好 -->
<meter min="0" max="100" low="60" high="85" optimum="0" value="68">
  磁盘已用 68%
</meter>

<!-- 考试分数 82 分,越高越好 -->
<meter min="0" max="100" low="60" high="85" optimum="100" value="82">
  得分 82
</meter>

配色规则由 optimum 落在哪个区间决定,浏览器会据此自动上色:

  • optimum 落在 [min, low) → 越低越好(典型例子:磁盘占用、错误率);
  • optimum 落在 (high, max] → 越高越好(典型例子:分数、好评率);
  • optimum 落在 [low, high] → 中间最好(典型例子:服务器 CPU 负载、体温)。

什么时候会用错?三个快速判断

遇到一个数值,按顺序问自己三句话:它会不会随时间自动涨到某个终点并"结束"?会,用 <progress>。它是不是某个刻度尺上的读数、还有明显的"好区间"和"坏区间"?是,用 <meter>。它是不是一个百分比但既没有完成态也没有好坏?那两者都不合适,直接用 <span> 加文本更诚实。

典型误用:用 <progress> 展示"内存占用 80%"(应该是 <meter>),用 <meter> 展示"文件上传 80%"(应该是 <progress>)。

样式怎么改?两者可定制程度差很多

<progress> 在 Chromium 内核(Chrome、Edge)里可以用 ::-webkit-progress-bar 和 ::-webkit-progress-value 定制,在 Firefox 里用 ::-moz-progress-bar,配合 appearance: none 去掉默认外观。不确定态的 <progress> 可以用 progress:indeterminate 伪类单独写样式。

<meter> 的可样式化程度明显更低:Firefox 支持 ::-moz-meter-bar 以及 :-moz-meter-optimum、:-moz-meter-sub-optimum、:-moz-meter-sub-sub-optimum 三个伪类,Chromium 内核则基本无法选中内部的填充条。如果你的设计稿要求渐变色的自定义仪表条,实用做法是保留 <meter> 的语义或用 role="meter" 的容器,再叠加自绘的视觉层。

无障碍与降级

给两个元素都加上能读出上下文的文本:<progress> 用 aria-label="上传进度",<meter> 用 aria-label="磁盘占用率",同时把关键数值写进元素内部的降级文本。<progress> 的进度值本身会由浏览器暴露给辅助技术,不需要额外 aria-valuenow;对 <meter> 则在支持度不完整的浏览器上建议补上可读文本,避免只靠颜色传达"好/坏"。

一句话收束:**有终点、会走完,用 <progress>(无 value 就是不确定态);有刻度、有优劣,用 <meter>(value 必填,low/high/optimum 决定配色),两者的样式定制能力和无障碍角色都不通用。**

版权声明:本文来自 GJ站长论坛《HTML 的 `<meter>` 和 `<progress>` 有什么区别?怎么用》
原文链接:https://www.gj0.com/thread-1093.html
转载请注明出处并保留本声明;内容仅代表作者观点,与本站立场无关。若本文涉嫌侵权,请联系本站处理。

全部回复 0

还没有回复,来抢沙发~