<meter> 标签不能用于展示文章阅读进度,因其语义仅适用于静态测量值(如体温、电量),而阅读进度属于动态任务完成比例,应使用 <progress> 标签,并配合 value、max 及可访问性文本实现正确语义与无障碍支持。

meter 标签**不能用于展示文章阅读进度**——它不是为滚动位置或动态加载状态设计的,强行用会语义错误、无障碍失效、且浏览器行为不可靠。
如果你看到有人写 <meter value="65" max="100">65%</meter> 来表示“已读 65%”,那只是视觉上像,实际在屏幕阅读器里会被读作“65 分之 100”,而不是“已阅读 65%”,搜索引擎也识别不出这是阅读进度。
为什么不能用 meter 表示阅读进度?
阅读进度是「任务完成比例」:用户正在执行一个有起点和终点的行为(从第一行滚到最后一行),属于进行中的过程。meter 只适用于「静态测量值」,比如「当前体温 36.8°C(范围 35–42)」或「电池剩余 42%(范围 0–100)」。progress 才是语义正确的选择。
progress 才是阅读进度的正确标签
必须同时设置 value 和 max,否则浏览器可能不渲染或截断为 100%:
-
value是当前已滚动比例(需 JS 计算并更新) -
max固定为100(百分比场景下最直观) - 内部文本如
已读 72%是给不支持progress的旧 UA 或屏幕阅读器用的 fallback,不是装饰
示例:
<progress value="72" max="100">已读 72%</progress>
注意:value 必须是数字,不能是字符串;超出 max 时多数浏览器静默截断,但逻辑已失真,JS 更新前应做校验。
立即学习“前端免费学习笔记(深入)”;
如何用 JS 动态计算并更新阅读进度
阅读进度本质是视口内内容高度占全文可滚动高度的比例,关键不是「滚动了多高」,而是「用户看到了多少内容」:
- 监听
scroll事件,但别直接用window.scrollY—— 它受 header、padding 等干扰 - 用
document.documentElement.scrollHeight获取总高度 - 用
window.innerHeight + window.scrollY估算可视区域底部位置 - 更可靠的做法是用 IntersectionObserver 监控文章容器的可见比例(尤其适合长文分段)
- 更新
<progress>时,直接改el.value = Math.min(100, Math.max(0, percent)),避免越界
样式兼容性与降级处理
原生 progress 默认样式差异大(Chrome 渐变、Firefox 单色、Safari 早期版本无填充),且无法用 background 直接覆盖:
- WebKit 浏览器可用
progress::-webkit-progress-bar和progress::-webkit-progress-value - Firefox 用
progress::-moz-progress-bar - 为保底兼容,可加 class 并用 CSS 模拟(如
<div class="reading-progress"><div style="width: 72%"></div></div>),但必须同步维护aria-valuenow和aria-valuemin/aria-valuemax - 千万别只靠视觉模拟而丢掉语义——没有
progress或对应 ARIA 属性,屏幕阅读器就只知道“一个 div”,不知道这是阅读进度



















