在前端开发中,进度条是最常见的 UI 组件之一。虽然已有许多现成插件,但为了满足定制化样式和动画需求,掌握纯 HTML/CSS 实现进度条的方法依然十分必要。本文将从基础标签说起,逐步深入到纯 CSS 的各种花式进度条,包括横向、圆环形、球形以及仿手机充电动画,并剖析常见问题如锯齿、样式兼容性等。
## 一、原生 HTML 标签:meter 与 progress
HTML5 提供了两个专门用于表示进度或度量的标签:`<meter>` 和 `<progress>`。
### 1. `<meter>` 标签
`<meter>` 用于表示已知范围内的标量测量值,例如温度、速度等。其属性包括 `min`(最小值)、`max`(最大值)和 `value`(当前值)。示例:- <p>
- <span>完成度:</span>
- <meter min="0" max="500" value="350">350 degrees</meter>
- </p>
复制代码
### 2. `<progress>` 标签
`<progress>` 用于表示任务的完成进度,例如文件上传、表单填写进度。属性 `max` 定义总工作量,`value` 定义已完成量。示例:- <p>
- <label for="file">完成度:</label>
- <progress max="100" value="70">70%</progress>
- </p>
复制代码
**两者语义区别**:`<meter>` 适用于固定范围内的数值(如汽车仪表盘时速),而 `<progress>` 更适合动态任务的进度(如加载百分比)。
### 3. 原生标签的局限性
尽管原生标签简单易用,但在实际生产环境中很少直接使用,原因包括:
- 无法统一修改背景色、前景色等样式。
- 不同浏览器的默认样式差异大,难以保证视觉效果一致。
- 无法添加动画、交互效果(如渐变、波纹)。
因此,更主流的做法是使用纯 CSS 模拟进度条,实现灵活可控的 UI。
## 二、纯 CSS 实现横向进度条
### 1. 百分比+渐变方案
最基础的横向进度条,通过 div 嵌套,用背景色百分比控制进度:- <div class="g-progress" style="--progress: 70%"></div>
复制代码 CSS 部分:- @property --progress {
- syntax: '<percentage>';
- inherits: false;
- initial-value: 0%;
- }
- .g-progress {
- width: 240px;
- height: 25px;
- border-radius: 25px;
- background: linear-gradient(90deg, #0f0, #0ff var(--progress), transparent 0);
- border: 1px solid #eee;
- transition: .3s --progress;
- }
复制代码 利用 `@property` 注册自定义属性,可实现进度平滑过渡动画。
## 三、纯 CSS 实现圆环形进度条
圆环形进度条的关键是使用角向渐变 `conic-gradient()`。一个典型示例:- <div class="progress-circle" style="background: radial-gradient(#fff 55%, transparent 56%), conic-gradient(#3A7CFF 70%, #f5f5f5 70.4%), radial-gradient(#fff 60%, #F1F3FC 0%);">
- <span class="progress-value">名称</span>
- <div class="totalvalbox">70%</div>
- </div>
复制代码 CSS 样式(SCSS 风格,可转为普通 CSS):- .progress-circle {
- position: relative;
- width: 149rpx;
- height: 149rpx;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .progress-value {
- position: absolute;
- text-align: center;
- width: 100%;
- font-weight: 400;
- font-size: 26rpx;
- line-height: 50rpx;
- }
- .totalvalbox {
- min-width: 217rpx;
- text-align: center;
- position: absolute;
- bottom: -50rpx;
- font-weight: 400;
- font-size: 30rpx;
- }
复制代码
### 锯齿问题与解决方案
角向渐变在不同颜色衔接处会出现明显锯齿,尤其是非整十的角度(如 27%)。解决方法是在衔接处留出微小过渡空间,例如将 `27%, #B5838D` 改为 `27%, #B5838D 27.2%`,增加 0.2% 的渐变宽容度。
### 圆角收尾的圆环形进度条
若进度条两端需要圆角(纯色场景),可在首尾叠加两个小圆点实现。若进度条为渐变色,则需借助 SVG 或 Canvas。示例:- <div class="g-container">
- <div class="g-progress"></div>
- <div class="g-circle"></div>
- </div>
复制代码 CSS:- .g-container {
- position: relative;
- width: 200px;
- height: 200px;
- margin: auto;
- }
- .g-progress {
- width: 100%;
- height: 100%;
- border-radius: 50%;
- background: conic-gradient(#FFCDB2 0, #FFCDB2 25%, #B5838D 25%, #B5838D);
- mask: radial-gradient(transparent, transparent 80px, #000 80.5px, #000 0);
- }
- .g-circle::before,
- .g-circle::after {
- content: '';
- position: absolute;
- top: 90px;
- left: 90px;
- width: 20px;
- height: 20px;
- border-radius: 50%;
- background: #FFCDB2;
- z-index: 1;
- }
- .g-circle::before {
- transform: translate(0, -90px);
- }
- .g-circle::after {
- transform: rotate(90deg) translate(0, -90px);
- }
复制代码 此外,利用多段角向渐变还能实现多色圆环(类似饼图)。
## 四、纯 CSS 实现球形进度条(波浪动画)
球形进度条通过波浪高度表示进度,核心是两层旋转的模糊圆和容器裁剪。
HTML:- <div class="container">
- <div class="wave-change"></div>
- <div class="wave"></div>
- <p>70%</p>
- </div>
复制代码 CSS:- .container {
- width: 200px;
- height: 200px;
- border: 5px solid rgb(118, 218, 255);
- border-radius: 50%;
- overflow: hidden;
- position: relative;
- }
- .wave-change {
- position: absolute;
- width: 200px;
- height: 200px;
- left: 0;
- top: 0;
- animation: change 12s infinite linear;
- }
- .wave-change::before,
- .wave-change::after {
- content: '';
- position: absolute;
- width: 400px;
- height: 400px;
- top: 0;
- left: 50%;
- border-radius: 45% 47% 43% 46%;
- background-color: rgba(255, 255, 255, .6);
- transform: translate(-50%, -70%) rotate(0);
- animation: rotate 7s linear infinite;
- z-index: 1;
- }
- .wave-change::after {
- border-radius: 47% 42% 46% 44%;
- background-color: rgba(255, 255, 255, .8);
- animation: rotate 9s linear -4s infinite;
- z-index: 2;
- }
- .wave {
- width: 200px;
- height: 200px;
- background-color: rgb(118, 218, 255);
- border-radius: 50%;
- }
- p {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- font-size: 36px;
- color: #000;
- z-index: 10;
- }
- @keyframes rotate {
- to { transform: translate(-50%, -70%) rotate(360deg); }
- }
- @keyframes change {
- from { top: 80px; }
- to { top: -120px; }
- }
复制代码 通过调整 `.wave-change` 的 `top` 值(从 80px 到 -120px)模拟 0% 至 100% 的进度变化。
## 五、炫酷充电动画(仿华为)
利用 CSS 的 `filter: contrast()` 和 `hue-rotate()` 可以实现类似手机充电动画的效果——动态气泡上升、颜色变化。
HTML 结构:- <div class="g-container">
- <div class="g-number">98.7%</div>
- <div class="g-contrast">
- <div class="g-circle"></div>
- <ul class="g-bubbles"></ul>
- </div>
- </div>
复制代码 核心 CSS 摘要:
- 外层容器设置 `filter: contrast(10) hue-rotate(0)` 并添加动画不断修改色相。
- 内部圆环使用模糊滤镜和旋转动画产生动态波纹。
- 气泡列表中的每个 li 随机位置和大小,通过 `moveToTop` 动画上升并逐渐透明。
完整代码较长,但核心原理是:通过 `contrast` 滤镜增强颜色对比度,`hue-rotate` 循环旋转色相,气泡模糊后与背景融合形成发光效果。动画可参考 CodePen 上的 “[Bars By Lucagaz](https://codepen.io/)” 作品。
## 六、总结
通过上述案例可以看出,纯 CSS 能够实现从简单到复杂的各类进度条,且支持动画和高度定制。核心技巧包括:
- 利用 `linear-gradient` 和 `conic-gradient` 绘制进度背景。
- 使用 `mask` 或 `radial-gradient` 实现空心圆环。
- 通过 `@property` 注册自定义属性实现平滑过渡。
- 利用 `transform`、`filter` 和 `animation` 创造动态效果。
掌握这些方法后,开发者可以完全摆脱对第三方进度条插件的依赖,根据需要快速构建出符合设计稿的进度组件。 |