三个显示型元素:output / progress / meter
表单不止于收集输入。规范在 4.10 一并定义了三个面向显示的元素:<output> 把计算或用户操作的结果讲给人(和辅助技术)听;<progress> 表示一项任务的进度;<meter>
表示已知范围内的标量量规。三者最常见的误用是把后两者搞混——progress 描述「事情做了多少」,meter 描述「某个量当前是多少」。本页逐个上手,并把它们与 <form> 元素的关系点清楚。
1 · <output>:一个会被播报的结果区
<output for="a b" name="result"> 表示一次计算的结果。它默认是一个 live region(隐含 ARIA role=status、aria-live=polite):当其文本变化时,屏幕阅读器会在空闲时主动播报新值。for
列出参与这次计算的控件 id(以空格分隔,IDL 端是 .htmlFor,一个 DOMTokenList);内容通过 .value 读写,.defaultValue 记下初值供表单 reset 时还原。下面拖两个滑块,求和会实时写进 output。
<output> 是 labelable、listed、resettable,但不是 submittable。它会出现在 form.elements 里、也能被 <label> 关联、表单 reset 时还原成 defaultValue;但它不进 entry list——即便写了
name,提交时 FormData 里也没有它的值。它是给人看的结果,不是要回传的数据。
2 · <progress>:任务进度,允许「不确定」
<progress value max> 表示一项任务完成了多少(如下载、上传)。给了 value 就是确定进度(determinate),浏览器按 value/max 画出占比;省略 value 则进入
indeterminate 状态——任务在跑、但说不清进度,浏览器画一条动态条。IDL 端:.value / .max,以及只读的 .position(确定时是
的占比,indeterminate 时固定为 -1)。
progress 不是量规。它没有 min、没有 low / high / optimum,也没有颜色语义——它表达的是「朝着完成推进」这件事。拿 progress 去显示「磁盘占用
80%」是误用:磁盘占用是一个静态标量,不是一项正在推进的任务,那是 meter 的活。
3 · <meter>:已知范围内的标量量规
<meter value min max low high optimum> 表示一个落在已知区间 [min, max] 内的标量:磁盘占用、评分、电量、CPU 负载。它和进度无关——不暗示「正在朝某处推进」,只回答「这个量当前算好还是差」。阈值 low / high 把区间切成低 / 中 / 高三段,optimum 落在哪一段就把那段定为「好」(绿);与「好」相邻的段是「一般」(黄),再远的那段是「差」(红)。下面拖 value,并切换 optimum,看同一个 value 在不同
optimum 下被判成完全不同的颜色。
颜色不看绝对大小,只看「离 optimum 那段有多远」。同一个 value=50(落在中段):当 optimum=90(在 high 段)时,中段与 high 相邻 → 判为黄;当 optimum=50(也在中段)时,中段即「好」段 → 判为绿。这正是
meter 与 progress 的本质差别:meter 携带「好坏」的价值判断,progress 只有「多少」。
| 维度 | <progress> |
<meter> |
|---|---|---|
| 语义 | 任务进度(朝完成推进) | 范围内的标量量规(当前是多少) |
| 典型用例 | 下载 / 上传 / 安装百分比 | 磁盘占用、评分、电量、负载 |
| 区间下界 | 隐含 0,无 min |
有 min(默认 0)与 max(默认 1) |
| 阈值 / 颜色语义 | 无 low / high / optimum,无好坏色 |
low / high / optimum 三者共同划绿 / 黄 / 红 |
| indeterminate | 支持:省略 value → 动态条,.position = -1 |
不支持:value 默认回退为 min |
| 关键 IDL | .value / .max / .position |
.value / .min / .max / .low / .high / .optimum |
4 · 三段源码并排
三个显示型元素各司其职:
<!-- output:计算结果,live region,不进提交 -->
<form>
<input type="range" id="a" /> + <input type="range" id="b" />
= <output for="a b" name="result">0</output>
</form>
<!-- progress:任务进度。省略 value = indeterminate -->
<progress value="30" max="100"></progress> <!-- 30% -->
<progress max="100"></progress> <!-- 不确定,position = -1 -->
<!-- meter:范围内的标量量规,有颜色语义 -->
<meter min="0" max="100"
low="30" high="70" optimum="90"
value="55"></meter> <!-- 55 在中段,optimum 在 high 段 → 黄 -->
progress 不是 meter,meter 不是进度条。最常见的两类误用:其一,用 <progress> 显示「磁盘已用 80% / 评分 4.2」这类静态标量——它们不是正在推进的任务,该用 <meter>;其二,用
<meter> 显示下载进度——meter 的绿 / 黄 / 红价值色会误导用户以为「进度低 = 出问题」,该用 <progress>。选元素先问一句:这是「一件事做了多少」还是「一个量现在是多少」。
<output> 是显示而非数据。它在 form.elements 里、能被 reset 还原,但不参与提交(不进 entry list)。需要把计算结果回传服务器时,应另用一个 <input type="hidden"> 承载数据,<output>
只负责把同一个值讲给人听。表单归属、entry list 的判定见 <form> 元素。
为什么 output 默认是 live region。它的隐含 ARIA role=status 带来 aria-live=polite:当你拖滑块、内容被改写时,屏幕阅读器会在用户停顿的间隙读出新结果,无需任何额外属性。这正是规范让它区别于一个普通
<span> 的地方——它天生就是「用来宣布结果」的元素。