我做了一些进度条。它们看起来像这样

它们不使用任何图像,只使用 CSS3 特效。就像一个优秀的设计师总是会做的那样,它们回退到完全可以接受的体验。以下是它们在 Opera 11 中的样子,Opera 11 支持此处使用的一些 CSS3,但并非全部。

正如您可能想象的那样,在完全不支持 CSS3 的浏览器中,外观将类似于上面所示,只是更加简化。
更新:已经过去一段时间了。本文最初写于 2011 年,并在 2015 年进行了更新,现在又在 2021 年更新。这次我只是修改了演示和代码笔,并删除了许多不再需要的供应商前缀内容。从语义上讲,您可能最好查看<progress>
和<meter>
元素。
HTML 基础
进度条本身将是一个带有<div>
类名的meter
。其中包含一个充当进度条“填充”区域的<span>
。这使用内联样式设置。它是知道填充进度条多远的标记,因此在这种情况下,内联样式非常有意义。CSS 替代方法是创建诸如“fill-10-percent”、“fill-one-third”或类似的类,这更繁重且灵活性较差。
基础
<div class="meter">
<span style="width: 25%"></span>
</div>
CSS 起始
div 包装器是进度条的轨道。我们不会设置宽度,因此它将像块级元素一样扩展到其父元素的宽度。不过您可以设置。高度也是任意的。此处设置为 20px,但可以是任何值。我们将尽可能多地在浏览器中圆角,并设置内阴影以使其具有一定的深度。
.meter {
height: 20px; <em>/* Can be anything */</em>
position: relative;
background: #555;
border-radius: 25px;
padding: 10px;
box-shadow: inset 0 -1px 1px rgba(255, 255, 255, 0.3);
}
然后内部的 span 将是进度条的填充部分。我们将使其显示为具有 100% 高度的块,因此它会伸展以适应它具有的任何空间。然后,我们将使用大量 CSS3 来赋予它渐变外观并圆角。
.meter > span {
display: block;
height: 100%;
border-top-right-radius: 8px;
border-bottom-right-radius: 8px;
border-top-left-radius: 20px;
border-bottom-left-radius: 20px;
background-color: rgb(43,194,83);
background-image: linear-gradient(
center bottom,
rgb(43,194,83) 37%,
rgb(84,240,84) 69%
);
box-shadow:
inset 0 2px 9px rgba(255,255,255,0.3),
inset 0 -2px 6px rgba(0,0,0,0.4);
position: relative;
overflow: hidden;
}
这些是基础。
其他颜色
让我们尽可能轻松地更改颜色。只需在 div 包装器中添加一个名为“orange”或“red”的类名,颜色就会被覆盖。
.orange > span {
background-color: #f1a165;
background-image: linear-gradient(to bottom, #f1a165, #f36d0a);
}
.red > span {
background-color: #f0a3a3;
background-image: linear-gradient(to bottom, #f0a3a3, #f42323);
}
条纹效果
我们可以通过在该 span 的顶部添加另一个元素并在其上放置重复的 CSS3 渐变来获得很酷的条纹效果。从语义上讲,这最好通过伪元素来实现,所以让我们这样做。我们将将其绝对定位在 span 的精确区域(该区域已具有相对定位)上,然后以相同的方式圆角,这样条纹就不会突出得奇怪。
.meter > span:after {
content: "";
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;
background-image: linear-gradient(
-45deg,
rgba(255, 255, 255, .2) 25%,
transparent 25%,
transparent 50%,
rgba(255, 255, 255, .2) 50%,
rgba(255, 255, 255, .2) 75%,
transparent 75%,
transparent
);
z-index: 1;
background-size: 50px 50px;
animation: move 2s linear infinite;
border-top-right-radius: 8px;
border-bottom-right-radius: 8px;
border-top-left-radius: 20px;
border-bottom-left-radius: 20px;
overflow: hidden;
}
我第一次从Lea Verou那里看到并获得了这个想法。
动画条纹
只有 Firefox 4 才能为伪元素设置动画,并且只有 WebKit 才能执行关键帧动画。因此,不幸的是,在为这些条纹设置动画方面,我们处于进退两难的境地。如果我们坚持这样做,让我们添加一个额外的 span,然后 WebKit 为其设置动画。
<div class="meter animate">
<span style="width: 50%"><span></span></span>
</div>
span 将与伪元素完全相同,因此我们将使用相同的值……
.meter > span:after, .animate > span > span {
……并避免重复
.animate > span::after {
display: none;
}
我们将背景位置移动到其大小的范围
@keyframes move {
0% {
background-position: 0 0;
}
100% {
background-position: 50px 50px;
}
}
并调用该动画
.meter > span::after, .animate > span > span {
animation: move 2s linear infinite;
}
不妨将动画也绑定到伪元素,这样一旦 WebKit 开始支持它,它就会起作用。
动画填充宽度
不幸的是,您无法为自动或自然宽度设置动画,这可能会让我们从强制为零的宽度动画到内联样式。
@keyframes expandWidth {
0% { width: 0; }
100% { width: auto; }
}
2012 年 1 月 25 日更新:事实证明,您可以可以为内联样式设置动画。只需在@keyframe
中省略“to”或“100%”结束值即可。
我已将其提交给主要浏览器的错误跟踪器,以推动其发展,但目前尚不支持。相反,让我们使用 jQuery 来实现。测量原始宽度,将其强制降低到零,然后动画恢复到原始宽度。
$(".meter > span").each(function() {
$(this)
.data("origWidth", $(this).width())
.width(0)
.animate({
width: $(this).data("origWidth") // or + "%" if fluid
}, 1200);
});
其他人的做法
嘿?!HTML5 怎么样?
哥们儿。HTML5 有专门为此设计的特性。<progress>
和<meter>
!是的,它确实有,但问题在于。这些元素已经具有非常特定的外观。默认情况下,它们看起来像您所在平台上其他地方使用的进度条。例如在 Mac 上

您可以像这样关闭该默认样式
progress {
-webkit-appearance: none;
}
这将允许您删除该默认样式中存在的闪亮效果,但您能做的仍然非常有限。您可以像这样更改内部的进度条
progress::-webkit-progress-bar-value {
-webkit-appearance: none;
background: orangered;
}
……而且之后您能用它做的事情也相当有限。更糟糕的是,在不同的浏览器之间,甚至在不同的 WebKit 浏览器之间,情况也大不相同。伪元素也无法一致地工作。我不想把事情悬而未决,但这确实是另一个时间的话题。总而言之,对于这些特定的进度条,div/span 方法目前是最佳选择。
哇,这些太棒了!
容器的圆角在 chrome/xp 中似乎有错误。
当您将“inset”box-shadow 与 border-radius 一起使用时,Chrome 会出现错误。请参阅http://code.google.com/p/chromium/issues/detail?id=128
有人知道解决方法吗?
谢谢,我会用到的,很酷
只是想留下评论,感谢您提到我自己尝试创建进度条。
我发现 jQuery 是(目前)动画进度条的唯一方法,但一旦浏览器支持允许,CSS3 确实会成为一种更好的方法。
嗨,David,
今天早上我使用 css3 对此进度条示例进行了一些模拟。
请查看:http://www.albybarber.com/css3
**仅在 -webkit- 浏览器中有效。**
您好,我有一个网站http://www.jkrt.org
想与您的网站进行友情链接
你使用了我的进度条!太酷了!
有趣的CSS3教程,但我不知道在哪里可以展示它。
棒极了,棒极了,棒极了!我对这方面了解不多,所以这太酷了!一个精心制作的进度条让我兴奋。
非常棒的结果
哇哇哇…太流畅了…颜色很好
很酷的颜色。感谢分享。
嘿,Chris,
感谢你发布我的实现并转发了前晚的推文!我感谢你所有的辛勤工作,在过去的几年里我从你那里学到了很多东西。干杯!
非常酷。谢谢!
这太棒了!Chris,干得好!
只想说,“HTML基础”标题后的下一段落下方应该有一个高亮的
span
,但它没有显示(至少在Chrome,win XP上是这样)。谢谢,已修复。
这些border-radius属性可以简写。只有Safari <5和iOS <3(WebKit 532.5之前的版本)在使用唯一圆角半径时会出现问题。
所以可以变成
如果你想要iOS 3.1和Saf4的支持
你可以把它加在上面。
伪元素/嵌套span上也不需要border-radius,因为“父”元素的overflow设置为hidden。
那个实际上不起作用,Nicolas,如果你保留隐藏的overflow但关闭border-radiusii,你会看到突出的部分。请看:http://cl.ly/4rTw 我认为这是一个bug。
我认为当进度条达到100%时,如果它的右端也能变成圆形(就像左端一样),而不是带有圆角的正方形,会更好。
太棒了!
谢谢!
哇,Chris,真是天才,我真的很喜欢它!
有没有办法减慢动画速度?
不用了!我犯了个错误,在JS中减少了值而不是增加了它。
嘿,兄弟,你是怎么做到的?请告诉我:) 我做不到 :p
(在移动网站上似乎无法回复其他人)
@Paul,border radius规范有变化吗?它过去总是多个值创建椭圆形角(虽然我个人从来不明白为什么这样做)。
无论如何,在这个例子中为什么需要不同的圆角半径?四个角不应该都一样吗?
太棒了
当进度条移动到末尾时,border-radius可以增加吗?
此源代码的HTML部分不符合W3C标准(XHTML-HTML5)。你不能在元素上指定style属性,它必须在样式表中。
CSS使用得很好,无论如何,最终结果看起来很棒并且完全可定制。
Nico
我一直在尝试使用进度条,并想出了一个有趣的方法来标记达到100%的进度条。
如果你使用百分比来指定宽度
.meter > span[style*="100"] { background: gray}
或者如果你使用像素来指定宽度
.meter > span[style*="470"] { background: gray}
当然,这个选择器容易受到其他内联样式中数字的影响,因此请谨慎使用。
这真的很酷!我一直以为加载图像或序列是某种编程。它就像一门我不懂的科学。
当它被解释给笨蛋的时候,感觉真好!谢谢
我的天啊,
太棒了,Chris。
我以为我对CSS有点了解,但我猜我对它一无所知:P
祝你工作顺利^_^
这对我的WordPress(样式)来说是个好消息
虽然所有这些东西都很酷,但它们不会被使用,直到CSS3和HTML5成为标准。我希望我们能在HTML标准方面提前几年……太多人还在使用IE7/IE8。啊!
非常酷,但你得让动画反向运行!这样进度条看起来比实际进度更快!这样看起来会更慢。
出色完成。可以轻松使用
我稍微调整了一下代码。我在标记中添加了一个span来保存百分比。
<div class="meter-wrapper">
<div class="meter"><span style="width:35%"></span></div>
<span class="progress">35%</span>
</div>
progress span在页面加载时隐藏,然后在进度条动画完成后淡入。
我还需要进度条在浏览器大小调整时随容器大小调整。jQuery的width()只返回px,所以我需要一个小的解决方法。
jQuery('.meter-wrapper .progress').hide();
jQuery(".meter > span").each(function() {
var w = ( 100 * parseFloat(jQuery(this).css('width')) / parseFloat(jQuery(this).parent().css('width')) ) + '%';
jQuery(this).width('0%').animate({width: w}, 1200, function() { jQuery('.meter-wrapper .progress').fadeIn(); } );
});
非常棒的工作!感谢分享…
但在Firefox 3中看起来很糟糕。
我真的很喜欢它的外观和功能!谢谢。
只想快速感谢一下——这是出色的有效代码,简单地解决了我的一个大问题!我非常高兴和感谢开源信息。
jenn.e.
嗨,Chris……我试图在我的管理员面板cms上使用这些进度条。无论如何,我想隐藏它(display:none;)并想从jquery fadeIn中显示它。当我尝试时,我注意到进度条的宽度没有完全准确。请帮我看看。这是我的代码。
CSS =>
Jquery =>
Html =>
我有一个有效的跨浏览器解决方案来解决meter元素(也可以用于progress)。
在FireFox中截取一个100%的meter(或进度条)的屏幕截图。在Photoshop中裁剪它以创建meter.png
然后
$meterValue = 90;
$meterOffset = $meterValue – 100;
<meter style="border:solid 1px #000;display:inline-block;width:84px;height:17px;background:url("img/meter.png") no-repeat scroll transparent -'.$meterOffset.'px 0px;" title="liked '.$meterValue.'% by users" value="'.$meterValue.'" min="0" max="100">'.$meterValue.'%</meter>
搞定!
抱歉……将你的进度条设置为100px 非常重要,这样才能正确偏移。太可惜了,你不能使用负百分比,否则就不会有这个问题了。
嗯,因为CSS是内联的,所以要么省略背景图片周围的双引号,要么使用单引号。
嗨,很棒的技巧!感谢分享。这几乎是我正在寻找的。
我尝试再做两件事,但不知道这种方法是否可行
1) 我想在背景之上放置一个带有透明度的图片。但没有效果。想象一个用png格式表示的空啤酒杯,在Illustrator中注册了透明度,这样杯子的内容就是空的。我梦想用动画背景填充杯子到30% 例如。为此,图片应该在上面,背景颜色在后面,以填充杯子。这可能吗?
2) 同样,是否可以使背景从div的底部到顶部增长,而不是像示例中那样从左到右增长?
非常感谢(以及对我的拙劣英语表示歉意……);-)
很酷的颜色。感谢分享。