HTML5 progress 元素

Avatar of Pankaj Parashar
Pankaj Parashar

DigitalOcean 为您的旅程的每个阶段提供云产品。 立即开始使用 $200 的免费积分!

以下是 Pankaj Parashar 的客座文章。 Pankaj 给我写信介绍了他创建的一些非常酷的样式进度元素。 我问他是否愿意将这个想法扩展成一篇关于一般样式的文章。 谢天谢地,他欣然同意,写下了这篇关于在 HTML 中使用它们、用 CSS 尽可能跨浏览器地对它们进行样式设置以及回退的优秀文章。

以下是进度元素的基本标记

<progress></progress>

根据 W3C 定义的标准,进度元素表示任务的完成进度。 进度元素 必须具有 开始标签(即 <progress>)和结束标签(即 </progress>),即使它看起来像一个替换元素(如输入)。 不过,这很好,因为它有助于回退内容,我们将在后面介绍。

除了全局属性外,它还可以具有另外两个属性

  • max – 指示在任务可以被认为已完成之前需要完成多少任务。 如果未指定,默认值为 1.0
  • value – 指示进度条的当前状态。 它必须大于或等于 0.0,小于或等于 1.0max 属性的值(如果存在)。

进度条的状态

进度条可以处于两种状态 - **不确定** 和 **确定**。

1. 不确定

Mac OS 10.8 上 Chrome 29 中进度条的不确定状态

根据您的浏览器和操作系统的组合,进度条可能看起来不同。 Zoltan “Du Lac” Hawryluk 在其关于 HTML5 进度条的文章中,以 极深的深度 涵盖了进度元素的跨浏览器行为(这绝对值得一读)。 Wufoo 在其 进度支持页面 上提供了一些在其他操作系统上的屏幕截图。

定位和设置不确定进度条的样式非常容易,因为我们知道它不包含 value 属性。 我们可以使用 CSS 否定子句 :not() 来设置它的样式

progress:not([value]) {
   /* Styling here */
}

2. 确定

在整篇文章中,我们将只关注设置进度条确定状态的样式。 因此,让我们通过添加 maxvalue 属性来更改状态。

<progress max="100" value="80"></progress>

在不应用任何 CSS 的情况下,进度条在 Mac OS 10.8 上的 Chrome 29 中看起来像这样。

Mac OS 10.8 上 Chrome 29 中进度条的确定状态
请注意,仅添加 max 属性不会更改进度条的状态,因为浏览器仍然不知道要表示哪个值。

这几乎是我们可以在 HTML 中做的所有事情,其余的工作由 CSS 完成。 在此阶段,我们不必担心支持不理解进度元素的旧浏览器的回退技术。

设置进度条的样式

我们可以使用 progress[value] 选择器来定位确定进度条。 只要您知道标记中没有不确定的进度条,使用 progress 就足够了。 我倾向于使用前者,因为它在两种状态之间提供了清晰的区分。 与任何其他元素一样,我们可以使用 widthheight 来为进度条添加尺寸

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 浏览器的用户代理样式表

要重置默认样式,我们只需将 -webkit-appearance 设置为 none

progress[value] {
  /* Reset the default appearance */
  -webkit-appearance: none;
   appearance: none;

  width: 250px;
  height: 20px;
}
重置后的进度条外观

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

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 来绘制进度元素。

Firebug 截图

通过使用 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 和 Opera 中的微弱边框

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 优秀的 polyfillFirefox 3.5-5、Opera 10.5-10.63、IE9-10 添加了几乎完全的支持。这还为 IE8 添加了部分支持。它包括将 progress-polyfill.js 文件添加到您的 HTML 中,并添加脚本文件使用的 CSS 选择器。要详细了解其用法,请查看 CSS 源代码 项目页面

2. HTML 回退

这是我偏爱的(无 JS)方法。它利用了 audiovideo 元素也使用的常用技术。

<progress max="100" value="80">
    <div class="progress-bar">
        <span style="width: 80%;">Progress: 80%</span>
    </div>
</progress>

使用进度标签内的 divspan 模拟进度条的外观和感觉。现代浏览器会忽略进度标签内的内容。无法识别进度元素的旧版浏览器会忽略标签并渲染其内部的标记。

.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 更新进度条的信息。