以下是 Pankaj Parashar 的客座文章。 Pankaj 给我写信介绍了他创建的一些非常酷的样式进度元素。 我问他是否愿意将这个想法扩展成一篇关于一般样式的文章。 谢天谢地,他欣然同意,写下了这篇关于在 HTML 中使用它们、用 CSS 尽可能跨浏览器地对它们进行样式设置以及回退的优秀文章。
以下是进度元素的基本标记
<progress></progress>
根据 W3C 定义的标准,进度元素表示任务的完成进度。 进度元素 必须具有 开始标签(即 <progress>
)和结束标签(即 </progress>
),即使它看起来像一个替换元素(如输入)。 不过,这很好,因为它有助于回退内容,我们将在后面介绍。
除了全局属性外,它还可以具有另外两个属性
max
– 指示在任务可以被认为已完成之前需要完成多少任务。 如果未指定,默认值为1.0
。value
– 指示进度条的当前状态。 它必须大于或等于0.0
,小于或等于1.0
或max
属性的值(如果存在)。
进度条的状态
进度条可以处于两种状态 - **不确定** 和 **确定**。
1. 不确定

根据您的浏览器和操作系统的组合,进度条可能看起来不同。 Zoltan “Du Lac” Hawryluk 在其关于 HTML5 进度条的文章中,以 极深的深度 涵盖了进度元素的跨浏览器行为(这绝对值得一读)。 Wufoo 在其 进度支持页面 上提供了一些在其他操作系统上的屏幕截图。
定位和设置不确定进度条的样式非常容易,因为我们知道它不包含 value
属性。 我们可以使用 CSS 否定子句 :not()
来设置它的样式
progress:not([value]) {
/* Styling here */
}
2. 确定
在整篇文章中,我们将只关注设置进度条确定状态的样式。 因此,让我们通过添加 max
和 value
属性来更改状态。
<progress max="100" value="80"></progress>
在不应用任何 CSS 的情况下,进度条在 Mac OS 10.8 上的 Chrome 29 中看起来像这样。

max
属性不会更改进度条的状态,因为浏览器仍然不知道要表示哪个值。这几乎是我们可以在 HTML 中做的所有事情,其余的工作由 CSS 完成。 在此阶段,我们不必担心支持不理解进度元素的旧浏览器的回退技术。
设置进度条的样式
我们可以使用 progress[value]
选择器来定位确定进度条。 只要您知道标记中没有不确定的进度条,使用 progress
就足够了。 我倾向于使用前者,因为它在两种状态之间提供了清晰的区分。 与任何其他元素一样,我们可以使用 width
和 height
来为进度条添加尺寸
progress[value] {
width: 250px;
height: 20px;
}
这是有趣的部分结束,事情变得复杂起来,因为每类浏览器都提供单独的伪类来设置进度条的样式。 为简化起见,我们实际上并不关心每个浏览器的哪些版本支持进度元素,因为我们的回退技术将处理其余部分。 我们将它们分类如下
- WebKit/Blink 浏览器
- Firefox
- Internet Explorer
WebKit/Blink (Chrome/Safari/Opera)
Google Chrome、Apple Safari 和最新版本的 Opera(16+)属于此类别。 从 webkit 浏览器的用户代理样式表 中可以明显看出,它们依赖于 -webkit-appearance: progress-bar
来设置进度元素的外观。

要重置默认样式,我们只需将 -webkit-appearance
设置为 none
。
progress[value] {
/* Reset the default appearance */
-webkit-appearance: none;
appearance: none;
width: 250px;
height: 20px;
}

在 Chrome 开发者工具 中进一步检查进度元素时,我们可以看到规范的实现方式。

WebKit/Blink 提供了两个伪类来设置进度元素的样式
-webkit-progress-bar
是可用于设置进度元素容器样式的伪类。 在此演示中,我们将更改进度元素容器的背景颜色、边框半径,然后应用内嵌阴影。-webkit-progress-value
是用于设置进度条内值的伪类。 此元素的background-color
默认情况下为绿色,这可以通过检查用户代理样式表来验证。 对于此演示,我们将在 background-image 属性上使用线性渐变来创建糖果条效果。
首先,我们将设置 -webkit-progress-bar
(容器)的样式
progress[value]::-webkit-progress-bar {
background-color: #eee;
border-radius: 2px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25) inset;
}

接下来,我们将使用多个渐变背景设置 -webkit-progress-value
(条形)的样式。 一个用于条纹,一个用于从上到下的阴影,一个用于从左到右的颜色变化。 我们将使用 -webkit- 前缀作为渐变,因为我们无论如何都将它用于进度条本身。
progress[value]::-webkit-progress-value {
background-image:
-webkit-linear-gradient(-45deg,
transparent 33%, rgba(0, 0, 0, .1) 33%,
rgba(0,0, 0, .1) 66%, transparent 66%),
-webkit-linear-gradient(top,
rgba(255, 255, 255, .25),
rgba(0, 0, 0, .25)),
-webkit-linear-gradient(left, #09c, #f44);
border-radius: 2px;
background-size: 35px 20px, 100% 100%, 100% 100%;
}

添加动画
在撰写本文时,只有 WebKit/Blink 浏览器支持对进度元素的动画。 我们将通过更改背景位置来动画化 -webkit-progress-value
上的条纹。
@-webkit-keyframes animate-stripes {
100% { background-position: -100px 0px; }
}
@keyframes animate-stripes {
100% { background-position: -100px 0px; }
}
并在 -webkit-progress-value
选择器本身使用此动画。
-webkit-animation: animate-stripes 5s linear infinite;
animation: animate-stripes 5s linear infinite;
**更新:** 动画似乎不再适用于 Blink 中进度元素内的伪元素。 在发布本文时,它们确实可以工作。 Brian LePore 向我报告了此事,并指出了 这个线程 进行讨论,并创建了 一个简化的测试用例。 Simuari 的想法
也许
<progress>
也一样,在 Shadow DOM 之外定义的 @keyframes 无法被里面的元素访问。 从时间上看,它可能在 Chromium 39/40 中发生了变化?
还有
似乎有效的方法是将动画从
progress::-webkit-progress-bar
移动到progress
Bardi Harborow 报告说情况并非如此,他还指出了 记录的错误。
伪元素
在撰写本文时,只有 WebKit/Blink 浏览器支持进度条上的 ::before
和 ::after
伪元素。 通过简单地查看进度条,无法确定实际值。 我们可以使用 ::before
或 ::after
在进度条的尾端显示实际值来解决此问题。
progress[value]::-webkit-progress-value::before {
content: '80%';
position: absolute;
right: 0;
top: -125%;
}

有趣的是,content: attr(value)
不适用于进度条。 但是,如果您在内容属性中明确指定文本,它就可以工作! 我一直 找不到 这种行为背后的原因。 由于这仅适用于 WebKit/Blink 浏览器,因此目前没有充分的理由在伪元素中嵌入内容,至少现在是这样。
**更新 2016 年 11 月:** progress::after { content: attr(value); } 似乎现在 在 Blink 中可以工作,但其他浏览器都不行。
类似地,::after
用于在进度条末尾创建漂亮的铰链效果。这些技术是实验性的,如果您追求跨浏览器一致性,不建议使用它们。
progress[value]::-webkit-progress-value::after {
content: '';
width: 6px;
height: 6px;
position: absolute;
border-radius: 100%;
right: 7px;
top: 7px;
background-color: white;
}
2. Firefox
与 WebKit/Blink 类似,Firefox 也使用 -moz-appearence: progressbar
来绘制进度元素。

通过使用 appearence: none
,我们可以摆脱默认的斜角和浮雕效果。不幸的是,这会在 Firefox 中留下一个微弱的边框,可以通过使用 border: none
来移除。这也能解决 Opera 12 的边框问题。
progress[value] {
/* Reset the default appearance */
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
/* Get rid of default border in Firefox. */
border: none;
/* Dimensions */
width: 250px;
height: 20px;
}

Firefox 提供了一个唯一的伪类(-moz-progress-bar
),我们可以用来定位进度条的值。这意味着我们无法在 Firefox 中设置容器的背景样式。
progress[value]::-moz-progress-bar {
background-image:
-moz-linear-gradient(
135deg,
transparent 33%,
rgba(0, 0, 0, 0.1) 33%,
rgba(0, 0, 0, 0.1) 66%,
transparent 66%
),
-moz-linear-gradient(
top,
rgba(255, 255, 255, 0.25),
rgba(0, 0, 0, 0.25)
),
-moz-linear-gradient(
left,
#09c,
#f44
);
border-radius: 2px;
background-size: 35px 20px, 100% 100%, 100% 100%;
}
Firefox 不支持进度条上的 ::before
或 ::after
伪类,也不支持进度条上的 CSS3 关键帧动画
,这导致我们的体验略有减少。
3. Internet Explorer
只有 IE 10+ 本机支持进度条,而且只支持部分功能。它只允许更改进度条值的颜色。IE 将进度条的值实现为 color
属性,而不是 background-color
。
progress[value] {
/* Reset the default appearance */
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
/* Get rid of default border in Firefox. */
border: none;
/* Dimensions */
width: 250px;
height: 20px;
/* For IE10 */
color: blue;
}
不支持进度条的浏览器怎么办?
进度元素在以下浏览器中得到原生支持:Firefox 16+、Opera 11+、Chrome、Safari 6+。IE10+ 部分支持它们。如果您想支持旧版浏览器,您有两个选择。
1. Lea Verou 的 HTML5 进度 polyfill
Lea Verou 优秀的 polyfill 为 Firefox 3.5-5、Opera 10.5-10.63、IE9-10 添加了几乎完全的支持。这还为 IE8 添加了部分支持。它包括将 progress-polyfill.js 文件添加到您的 HTML 中,并添加脚本文件使用的 CSS 选择器。要详细了解其用法,请查看 CSS 源代码 项目页面。
2. HTML 回退
这是我偏爱的(无 JS)方法。它利用了 audio
和 video
元素也使用的常用技术。
<progress max="100" value="80">
<div class="progress-bar">
<span style="width: 80%;">Progress: 80%</span>
</div>
</progress>
使用进度标签内的 div
和 span
模拟进度条的外观和感觉。现代浏览器会忽略进度标签内的内容。无法识别进度元素的旧版浏览器会忽略标签并渲染其内部的标记。
.progress-bar {
background-color: whiteSmoke;
border-radius: 2px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.25) inset;
width: 250px;
height: 20px;
position: relative;
display: block;
}
.progress-bar > span {
background-color: blue;
border-radius: 2px;
display: block;
text-indent: -9999px;
}
通常将这两种技术结合使用,这对生产网站来说是完全安全的。一旦您掌握了对单个进度条的样式设置,那么添加多个进度条的样式就仅仅是一项练习,可以通过类来完成。
请查看 CodePen 上 CSS-Tricks (@css-tricks) 编写的 使用 HTML5 进度条和 CSS3 动画的技能集。
该演示应该在所有浏览器中正常运行,包括 Internet Explorer(降至 IE 8)。进度条颜色在所有版本的 Internet Explorer 中都是蓝色。Opera 11 和 12 不允许更改进度条颜色。因此,它显示默认的绿色。该演示使用额外的标记来显示有关进度条和百分比值的元信息。
要了解更多信息,请查看 HTML5 Doctor 文章。它涵盖了一些类似的内容,但也包含一些关于其他属性以及如何在需要时使用 JavaScript 更新进度条的信息。
嘿,谢谢,太棒了。我一定会使用它!
Firefox
为什么有 webkit
::-webkit-progress-bar
::-webkit-progress-value
?
这是一个很好的观点!但不幸的是,对于 Webkit/Blink 浏览器,进度元素没有直接与
progress[value]
选择器挂钩。因此,上面的代码在这些浏览器中将无法工作。您可以通过在开发者工具中检查
progress
元素来深入了解实现,并了解更多有关规范实现的信息。我认为文章的 URL 应该写成:
https://css-tricks.org.cn/html5-progress-element/
而不是
https://css-tricks.org.cn/html5-element/
是打字错误吗?
Safari 5(以及 iOS 5 中的 Mobile Safari)中存在一个错误,导致 PROGRESS 元素实际上被完全销毁,无影无踪。这使得无法进行 polyfill,除非您将回退元素放在 PROGRESS 元素之外。
这主要是一个 Windows Safari 用户的问题(他们仍然停留在 5 版本)。大多数 OS X 和 iOS 用户已经迁移到更高版本。
感谢您指出这一点。
我知道 Safari 5 存在这个问题,但不知道它会完全销毁
<progress>
元素。我认为回退标记在任何情况下都能正常工作。您介意分享一下这个异常现象的截图吗?
真是太不幸了。
但是,Windows 上 Safari 的采用率是多少?我认为它低于 IE7,甚至可能低于 IE6。
大多数旧用户已经从那时起切换到 Chrome(或其他浏览器)。
此链接 - https://w3schools.org.cn/browsers/browsers_safari.asp 显示了不同版本 Safari 的使用统计数据。
7 月份所有平台上 Safari 5 的使用率为 0.8%。对于 Windows,它应该比 IE7/6 还要低。
@Ron,我认为 Safari 5(5.1.7),迄今为止适用于 Windows 的最后一个版本,在性能方面存在很多原生问题。它已经困扰我很久了。大多数 CSS3 过渡和变换都有错误,而且会闪烁,导致 Safari 崩溃并重启。大多数通过 jQuery 进行的过渡似乎也遵循相同的顺序。我认为这只会导致 Web 社区最终完全忽视 Windows 版 Safari,就像对 Opera 那样。我希望 iOS 版 Safari 6 没有这个问题。
感谢您撰写这篇完整的文章,Pankaj!样式设置部分对我正在进行的项目非常有用。
我过去也遇到过
content: "attr(data-value);
的问题,这有点令人恼火。伪元素中的伪元素。InCSSeption。
Pankaj,干得好。:)
谢谢,Hugo!
这里的内容真的非常棒!我实际上并不知道任何 HTML5 进度代码,但我一定会在我的下一个网站中使用它 - 谢谢!
干得好,好文章。
这意味着那些顽固的 IE 6 用户可以以其全部荣耀看到它们吗?:D 我认为它应该写成“降至 IE 8”。
但是很棒的技术。无 JS 回退也很好,而且很简单。我喜欢它。
啊,你抓到我了!但更重要的是,你抓住了重点。:-) 我可能从 IE11 开始测试,并成功地测试了所有版本,直到 IE8!但你说得对,它应该写成降至 IE8。
我已经修复了,谢谢!由于它不再相关,我将把它埋掉。
昨天我刚想找这方面的更多信息,然后今天就在这里找到了 :)
感谢您的信息,继续努力。
问题是,目前还没有合适的方法可以用 CSS 样式化进度条,这就是为什么每个浏览器都做出了完全不同的东西(也可能是为什么 Webkit 会使用奇怪的方法来样式化它们)。
在有官方方法使用 CSS 样式化进度条之前,我们要么只能忍受这些疯狂的样式,要么就使用其他 HTML 元素,完全忽略
<progress>
。官方方法… 为什么我回复的时候总要打错字 -_-‘
一切都很好,除了那些专有属性仍然让我想起所谓的“开放式网络平台”还没有那么开放,或者至少在某些地方没有共同一致的“基础”。更不用说所谓的“有风险的功能”(你今天使用它,却担心它下个月可能会从规范中消失),以及轻描淡写地说,“分散的”文档。这就是我多年来一直更喜欢 Flash 的原因。一致性!
总之,这是一篇非常有信息量和有用的文章。干得好,Pankaj。
感谢你的想法,Wojciech。我可以想象开发人员在样式化进度条时所忍受的痛苦,而这篇文章就是试图减少这种痛苦。
但是,这种情况无法改善,除非不同浏览器引擎对 HTML5 进度条元素规范的实现能够做到跨浏览器一致。
你好,Pankaj,
为什么你会使用带有两个冒号的伪元素 :before 和 :after?
不应该使用 ::after 而不是 ::after 吗?
再见,Kevin
事实上,伪元素应该写成
::after
和::before
,以免与像:hover
、:active
等伪选择器混淆。我想我在一篇旧文章中读到过。;)
Kevin –
简短答案 –
:before
和::before
之间没有区别,:after
和::after
之间也没有区别。长答案 – 阅读由 W3C 在伪元素上定义的规范,其中指出,
这确实是 HTML5 的一个非常棒的功能。我非常喜欢它。我已经在我的网站上实现了它。它运行得非常出色。感谢您分享如此出色的东西。
虽然这篇文章只是间接地提到了这一点,但我必须说,在阅读这篇文章并在前几天在一个项目中实现了这个功能之后,如果想要在主条上使用任何“花哨的效果”,我建议现在不要使用进度条元素。
为什么呢?
简而言之:IE10。由于你只能通过颜色属性对条形进行着色,因此与 Chrome 和 Firefox 相比,条形看起来非常平坦和单调,这真的很令人遗憾,因为 IE10 支持 CSS 渐变和动画。即使在 IE8/IE9 中(通过回退),你也可以使用 filter 属性获得漂亮的渐变填充。如果你使用普通的 DIV 和 SPAN,你将节省大量的额外 CSS,并获得更好的视觉支持。
也就是说,我真的很想让它奏效… 但是 IE10 实在太让人沮丧了 :(
很棒的指南,哥们,现在我要在我的新 CSS3 网站中添加加载条。
这真的很酷。
使用原生解决方案比自己用 divs 创建一个更容易。可惜的是,我们可能要等到 IE11 才能获得完全支持。
关于 Firefox/Gecko 实现的两个问题
– 你实际上可以用 ::indeterminate 伪类来样式化不确定的进度条
progress::indeterminate {
/* */
}
– 你可以通过简单地样式化进度元素来样式化进度条背景,例如
progress {
background-color: blue;
}
progress::-moz-progress-bar {
background-color: red;
}
感谢你的评论。你提到了几个有效的问题,值得添加到文章中。
我不知道为什么,但我不需要使用外观重置。我在 Mac 上工作。
我也在 Mac 上工作!但是,在使用
webkit/blink
或-moz
浏览器时,仍然需要先重置外观。content: attr(value)
在 Chrome 中对我来说运行良好。一开始我犯了和你一样的错误,把它应用到了
-webkit-progress-value
元素而不是progress
元素。你好,Patrick – 将伪元素应用到
-webkit-progress-value
是有意的,并不是真正的错误 :) 我们现在在 StackOverflow 上解决了这个查询。很棒的文章!
只有一点小细节:
<progress><div></div></progress>
无法验证。最好使用“短语内容”元素代替(比如
<span>
)啊!这是一个很好的发现。虽然,W3C 验证并不是一个决定性的因素,但你的建议是正确的。
它有什么像 change 这样的事件吗?因为我看到 change 事件对它不起作用。
嗨,我来自意大利,太棒了,谢谢!我只有一个问题,如果我想将颜色边界固定在条形之外而不是条形本身,以便条形可以根据百分比改变颜色,我该怎么做?谢谢!
你是如何那样深入地研究
progress
元素的?我也有同样的疑问——你需要启用一个设置吗?其他浏览器也有吗?我希望能够在 DOM 改变它之前看到标记。
关于这个主题的一些更新…
Ayrton Fidelis 写道
以及 我们链接到 Jonathan Snook 文章,谈论动画进度条。