必须加 appearance: none 才能自定义 progress 样式,否则浏览器按原生控件渲染;需分别适配 webkit(::-webkit-progress-bar/value)、firefox(::-moz-progress-bar)伪元素;height 和 border-radius 必须在伪元素上重复设置;禁用 transition,用 js + requestanimationframe 实现平滑动画。

progress 必须加 appearance: none 才能重置样式
直接写 progress { background: #f0f0f0; border-radius: 4px; } 几乎无效——因为浏览器把 <progress></progress> 当作替换元素(replaced element),默认走原生控件渲染逻辑。appearance: none 是打开自定义大门的钥匙,不加它,WebKit 和 Firefox 的伪元素规则大概率被忽略。
注意:appearance: none 在 Safari 15.4+ 和 Chrome 93+ 中已稳定支持;Firefox 从 89 开始支持,但需配合 ::-moz-progress-bar 使用。旧版 IE 完全不支持,必须 fallback。
-
appearance: none要写在progress元素本身上,不能只写在 class 里漏掉基础选择器 - 加了之后,
border、height、width才真正可控;否则height只影响外层容器,内部填充条仍细窄 - 某些旧版 Chrome(如 v87)下,不加
appearance: none时::-webkit-progress-value的background会失效
Chrome/Edge 和 Firefox 的伪元素必须分开写全
WebKit 内核(Chrome、Edge、Safari)用 ::-webkit-progress-bar 和 ::-webkit-progress-value 控制轨道与填充;Firefox 只认 ::-moz-progress-bar,且它不支持独立设高或圆角,只能靠父级 height + border-radius 裁剪。
漏掉任一,对应浏览器就会回退到丑陋的系统默认样式——比如 Firefox 下没写 ::-moz-progress-bar,进度条就变成浅橙色粗条,毫无设计感。
- Chrome/Edge:必须同时覆盖
::-webkit-progress-bar(轨道)和::-webkit-progress-value(填充),二者border-radius值要一致,否则圆角断裂 - Firefox:只写
::-moz-progress-bar即可控制填充色,但轨道底色得靠progress自身的background-color或::before模拟 - Safari 15.4+ 开始支持标准
::progress-value,但为兼容旧版,建议三者并存声明
height 和圆角容易踩坑:不是设在 progress 上就生效
progress { height: 12px; border-radius: 6px; } 看似合理,实际只让外层盒子变圆,内部填充条边缘仍是直角——因为圆角必须作用在伪元素上,而高度控制逻辑各浏览器不同。
Chrome/Edge 下,::-webkit-progress-bar 和 ::-webkit-progress-value 都要显式设 height: 100%,否则填充条会被压缩;Firefox 下 ::-moz-progress-bar 不响应 height,只能靠 progress 的 height 配合 transform: scaleY() 拉伸(有锯齿风险,慎用)。
- 推荐统一用
height: 12px设在progress上,再分别给三个伪元素设height: 100%或等效处理 -
border-radius必须重复写进::-webkit-progress-bar、::-webkit-progress-value、::-moz-progress-bar三处,缺一不可 - 避免用
em或百分比设height,缩放页面时易失真;固定像素值最稳
动态更新 value 时,别依赖 CSS transition
给 ::-webkit-progress-value 加 transition: width 0.3s 听起来很美,但 Firefox 完全不支持,Chrome 下频繁更新(如每 50ms)还容易掉帧或跳变。原生 <progress></progress> 的动画由浏览器内部控制,CSS 过渡反而干扰它。
真正可靠的动效是 JS 逐步更新 value,配合 requestAnimationFrame 平滑驱动;样式层保持极简——纯色 background,禁用 box-shadow、border、渐变等重绘开销大的属性。
- 不要对
progress元素本身写:hover,它不响应伪元素内的悬停;要用 wrapper 包一层再写 - 想加动画感?删掉所有
transition,改用 JS 控制el.value = Math.min(max, current)逐帧赋值 - IE 无解,必须用
<div role="progressbar"> + <code>aria-valuenowfallback跨浏览器统一的关键不在“怎么写更炫”,而在“哪些必须写、哪些坚决不能碰”。伪元素清单、
appearance: none、固定高度、无过渡——这四点卡死,样式才不会在某个浏览器里突然崩掉。











