html原生不支持不确定状态,必须用css动画模拟:通过linear-gradient背景位移实现水平流动效果,并添加role="progressbar"和aria-valuetext确保可访问性。

HTML原生<progress></progress>不支持不确定状态
浏览器原生的 <progress></progress> 元素必须指定 value 和 max,否则会渲染为“0% 完成”的确定进度条,甚至部分浏览器(如 Safari)直接不显示。它没有 indeterminate 属性——这不是遗漏,是规范本身就没定义这个行为。
用 <progress></progress> 模拟不确定状态要绕开 value
真正能触发浏览器“不确定进度条”视觉效果的,只有 <progress></progress> 在 **缺失 value 属性且存在 max** 的情况下,但此时多数浏览器(Chrome/Firefox)仍会 fallback 到 0%;唯一可靠路径是放弃 <progress></progress>,改用语义更合适的 <meter></meter> 或纯 CSS 实现。
- Chrome 120+ 对
<progress max="100"></progress>(无value)会显示动画条,但这是非标准行为,不能依赖 - Firefox 显示为空白或 0% 条,Safari 直接不渲染
- 若强行加
value="0"再用 JS 删除,会触发重排,UI 闪动
CSS 实现最稳:用 @keyframes + background
主流框架(Ant Design、Material UI)和 Chrome DevTools 加载态都用 CSS 动画模拟不确定进度条,核心是线性移动的渐变背景:
<div class="progress-indeterminate"></div>
<p>.progress-indeterminate {
height: 4px;
background: linear-gradient(90deg, transparent, #1890ff, transparent);
background-size: 200% 100%;
animation: indeterminate 2s infinite;
}</p><p>@keyframes indeterminate {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}</p>
- 动画方向必须是
90deg(水平),180deg会垂直滚动,不符合习惯 -
background-size设为200% 100%才能保证两端透明过渡不突兀 - 不要用
transform: translateX()移动子元素——滚动区域易被父容器裁剪
需要语义化?用 <div role="progressbar"> 补 ARIA<p>屏幕阅读器无法识别纯 CSS 进度条,必须手动补全可访问性信息:</p>
<ul>
<li>加 <code>role="progressbar" 告诉辅助技术这是一个进度组件
aria-valuetext="loading"(不能写 aria-valuenow,因为无确定值)<span aria-live="polite">上传中…</span>
不确定进度条的本质不是“数值未更新”,而是“完成时间不可知”——这点在代码里没法自动推断,得靠开发者明确表达。











