Foundation 进度条
Foundation 进度条用于显示任务完成的进度或状态。本章将介绍 Foundation 进度条的各种用法。
基本进度条
使用 .progress 和 .progress-meter 创建基本进度条:
html
<div class="progress" role="progressbar" tabindex="0" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100">
<div class="progress-meter" style="width: 50%"></div>
</div>不同进度值
html
<div class="progress">
<div class="progress-meter" style="width: 0%"></div>
</div>
<div class="progress">
<div class="progress-meter" style="width: 25%"></div>
</div>
<div class="progress">
<div class="progress-meter" style="width: 50%"></div>
</div>
<div class="progress">
<div class="progress-meter" style="width: 75%"></div>
</div>
<div class="progress">
<div class="progress-meter" style="width: 100%"></div>
</div>进度条颜色
Foundation 提供了多种颜色选择:
html
<div class="progress primary">
<div class="progress-meter" style="width: 50%"></div>
</div>
<div class="progress secondary">
<div class="progress-meter" style="width: 50%"></div>
</div>
<div class="progress success">
<div class="progress-meter" style="width: 50%"></div>
</div>
<div class="progress warning">
<div class="progress-meter" style="width: 50%"></div>
</div>
<div class="progress alert">
<div class="progress-meter" style="width: 50%"></div>
</div>颜色用途说明
| 类名 | 颜色 | 常见用途 |
|---|---|---|
.primary | 蓝色 | 默认进度 |
.secondary | 灰色 | 次要进度 |
.success | 绿色 | 成功/完成 |
.warning | 黄色 | 警告/注意 |
.alert | 红色 | 危险/错误 |
带文本的进度条
在进度条内显示文本:
html
<div class="progress" role="progressbar" tabindex="0">
<span class="progress-meter" style="width: 50%">
<p class="progress-meter-text">50%</p>
</span>
</div>不同位置的文本
html
<style>
.progress-with-label {
position: relative;
}
.progress-label {
position: absolute;
width: 100%;
text-align: center;
line-height: 1rem;
color: #333;
font-size: 0.75rem;
font-weight: bold;
}
</style>
<div class="progress progress-with-label">
<span class="progress-meter success" style="width: 75%"></span>
<span class="progress-label">75% 完成</span>
</div>原生 HTML5 进度条
Foundation 也支持原生 <progress> 元素:
html
<progress max="100" value="75"></progress>样式化原生进度条
html
<style>
progress {
width: 100%;
height: 1rem;
-webkit-appearance: none;
appearance: none;
}
progress::-webkit-progress-bar {
background-color: #e6e6e6;
border-radius: 0;
}
progress::-webkit-progress-value {
background-color: #1779ba;
}
progress::-moz-progress-bar {
background-color: #1779ba;
}
</style>
<progress max="100" value="75"></progress>条纹进度条
添加条纹效果:
html
<style>
.progress.striped .progress-meter {
background-image: linear-gradient(
45deg,
rgba(255, 255, 255, 0.15) 25%,
transparent 25%,
transparent 50%,
rgba(255, 255, 255, 0.15) 50%,
rgba(255, 255, 255, 0.15) 75%,
transparent 75%,
transparent
);
background-size: 1rem 1rem;
}
</style>
<div class="progress primary striped">
<div class="progress-meter" style="width: 60%"></div>
</div>动画进度条
添加动画效果:
html
<style>
.progress.animated .progress-meter {
animation: progress-bar-stripes 1s linear infinite;
background-image: linear-gradient(
45deg,
rgba(255, 255, 255, 0.15) 25%,
transparent 25%,
transparent 50%,
rgba(255, 255, 255, 0.15) 50%,
rgba(255, 255, 255, 0.15) 75%,
transparent 75%,
transparent
);
background-size: 1rem 1rem;
}
@keyframes progress-bar-stripes {
from { background-position: 1rem 0; }
to { background-position: 0 0; }
}
</style>
<div class="progress success animated">
<div class="progress-meter" style="width: 75%"></div>
</div>进度条高度
自定义进度条高度:
html
<style>
.progress.thin { height: 0.5rem; }
.progress.thick { height: 1.5rem; }
.progress.extra-thick { height: 2rem; }
</style>
<div class="progress thin primary">
<div class="progress-meter" style="width: 50%"></div>
</div>
<div class="progress primary">
<div class="progress-meter" style="width: 50%"></div>
</div>
<div class="progress thick primary">
<div class="progress-meter" style="width: 50%"></div>
</div>
<div class="progress extra-thick primary">
<div class="progress-meter" style="width: 50%"></div>
</div>堆叠进度条
显示多个值在同一进度条中:
html
<style>
.progress-stacked {
display: flex;
background-color: #e6e6e6;
border-radius: 0;
height: 1.5rem;
}
.progress-stacked .progress-segment {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 0.75rem;
}
</style>
<div class="progress-stacked">
<div class="progress-segment" style="width: 30%; background: #3adb76;">已完成 30%</div>
<div class="progress-segment" style="width: 20%; background: #1779ba;">进行中 20%</div>
<div class="progress-segment" style="width: 15%; background: #ffae00;">待审核 15%</div>
</div>圆形进度条
使用 SVG 创建圆形进度条:
html
<style>
.circular-progress {
width: 100px;
height: 100px;
position: relative;
}
.circular-progress svg {
transform: rotate(-90deg);
}
.circular-progress .bg {
fill: none;
stroke: #e6e6e6;
stroke-width: 8;
}
.circular-progress .meter {
fill: none;
stroke: #1779ba;
stroke-width: 8;
stroke-linecap: round;
stroke-dasharray: 283;
stroke-dashoffset: calc(283 - (283 * var(--progress)) / 100);
transition: stroke-dashoffset 0.5s ease;
}
.circular-progress .value {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 1.25rem;
font-weight: bold;
}
</style>
<div class="circular-progress" style="--progress: 75">
<svg width="100" height="100">
<circle class="bg" cx="50" cy="50" r="45"></circle>
<circle class="meter" cx="50" cy="50" r="45"></circle>
</svg>
<span class="value">75%</span>
</div>进度条与标签
结合标签显示状态:
html
<div class="grid-x grid-margin-x">
<div class="cell small-10">
<div class="progress success">
<div class="progress-meter" style="width: 100%"></div>
</div>
</div>
<div class="cell small-2">
<span class="label success">完成</span>
</div>
</div>
<div class="grid-x grid-margin-x">
<div class="cell small-10">
<div class="progress warning">
<div class="progress-meter" style="width: 60%"></div>
</div>
</div>
<div class="cell small-2">
<span class="label warning">60%</span>
</div>
</div>
<div class="grid-x grid-margin-x">
<div class="cell small-10">
<div class="progress alert">
<div class="progress-meter" style="width: 25%"></div>
</div>
</div>
<div class="cell small-2">
<span class="label alert">25%</span>
</div>
</div>JavaScript 动态更新
基本更新
javascript
function updateProgress(element, value) {
var meter = element.querySelector('.progress-meter');
meter.style.width = value + '%';
// 更新 ARIA 属性
element.setAttribute('aria-valuenow', value);
// 如果有文本,更新文本
var text = meter.querySelector('.progress-meter-text');
if (text) {
text.textContent = value + '%';
}
}
// 使用
var progressBar = document.querySelector('.progress');
updateProgress(progressBar, 75);模拟加载进度
javascript
function simulateProgress(element, duration) {
var meter = element.querySelector('.progress-meter');
var start = 0;
var end = 100;
var startTime = null;
function animate(currentTime) {
if (!startTime) startTime = currentTime;
var elapsed = currentTime - startTime;
var progress = Math.min((elapsed / duration) * end, end);
meter.style.width = progress + '%';
element.setAttribute('aria-valuenow', Math.round(progress));
if (progress < end) {
requestAnimationFrame(animate);
}
}
requestAnimationFrame(animate);
}
// 5秒内完成
simulateProgress(document.querySelector('.progress'), 5000);完整示例
html
<!DOCTYPE html>
<html class="no-js" lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Foundation 进度条示例</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/foundation-sites@6.7.5/dist/css/foundation.min.css">
<style>
.demo-section {
margin-bottom: 30px;
}
.demo-section h3 {
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 1px solid #ddd;
}
.progress { margin-bottom: 10px; }
.progress.thin { height: 0.5rem; }
.progress.thick { height: 1.5rem; }
.progress.striped .progress-meter,
.progress.animated .progress-meter {
background-image: linear-gradient(
45deg,
rgba(255, 255, 255, 0.15) 25%,
transparent 25%,
transparent 50%,
rgba(255, 255, 255, 0.15) 50%,
rgba(255, 255, 255, 0.15) 75%,
transparent 75%,
transparent
);
background-size: 1rem 1rem;
}
.progress.animated .progress-meter {
animation: progress-bar-stripes 1s linear infinite;
}
@keyframes progress-bar-stripes {
from { background-position: 1rem 0; }
to { background-position: 0 0; }
}
.progress-stacked {
display: flex;
background-color: #e6e6e6;
height: 1.5rem;
margin-bottom: 10px;
}
.progress-stacked .progress-segment {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 0.75rem;
}
.progress-with-label {
position: relative;
}
.progress-label {
position: absolute;
width: 100%;
text-align: center;
line-height: 1rem;
color: #fff;
font-size: 0.75rem;
font-weight: bold;
top: 0;
}
.circular-progress {
width: 100px;
height: 100px;
position: relative;
display: inline-block;
margin: 10px;
}
.circular-progress svg { transform: rotate(-90deg); }
.circular-progress .bg {
fill: none;
stroke: #e6e6e6;
stroke-width: 8;
}
.circular-progress .meter {
fill: none;
stroke-width: 8;
stroke-linecap: round;
stroke-dasharray: 283;
stroke-dashoffset: calc(283 - (283 * var(--progress)) / 100);
transition: stroke-dashoffset 0.5s ease;
}
.circular-progress .value {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 1.25rem;
font-weight: bold;
}
</style>
</head>
<body>
<div class="grid-container">
<h1>Foundation 进度条展示</h1>
<div class="demo-section">
<h3>基本进度条</h3>
<div class="progress">
<div class="progress-meter" style="width: 25%"></div>
</div>
<div class="progress">
<div class="progress-meter" style="width: 50%"></div>
</div>
<div class="progress">
<div class="progress-meter" style="width: 75%"></div>
</div>
<div class="progress">
<div class="progress-meter" style="width: 100%"></div>
</div>
</div>
<div class="demo-section">
<h3>不同颜色</h3>
<div class="progress primary">
<div class="progress-meter" style="width: 60%"></div>
</div>
<div class="progress secondary">
<div class="progress-meter" style="width: 60%"></div>
</div>
<div class="progress success">
<div class="progress-meter" style="width: 60%"></div>
</div>
<div class="progress warning">
<div class="progress-meter" style="width: 60%"></div>
</div>
<div class="progress alert">
<div class="progress-meter" style="width: 60%"></div>
</div>
</div>
<div class="demo-section">
<h3>带文本的进度条</h3>
<div class="progress thick primary progress-with-label">
<span class="progress-meter" style="width: 65%"></span>
<span class="progress-label">65% 完成</span>
</div>
</div>
<div class="demo-section">
<h3>不同高度</h3>
<p>Thin:</p>
<div class="progress thin primary">
<div class="progress-meter" style="width: 50%"></div>
</div>
<p>Default:</p>
<div class="progress primary">
<div class="progress-meter" style="width: 50%"></div>
</div>
<p>Thick:</p>
<div class="progress thick primary">
<div class="progress-meter" style="width: 50%"></div>
</div>
</div>
<div class="demo-section">
<h3>条纹进度条</h3>
<div class="progress primary striped">
<div class="progress-meter" style="width: 60%"></div>
</div>
<div class="progress success striped">
<div class="progress-meter" style="width: 60%"></div>
</div>
</div>
<div class="demo-section">
<h3>动画进度条</h3>
<div class="progress primary animated">
<div class="progress-meter" style="width: 75%"></div>
</div>
<div class="progress success animated">
<div class="progress-meter" style="width: 75%"></div>
</div>
</div>
<div class="demo-section">
<h3>堆叠进度条</h3>
<div class="progress-stacked">
<div class="progress-segment" style="width: 35%; background: #3adb76;">已完成</div>
<div class="progress-segment" style="width: 25%; background: #1779ba;">进行中</div>
<div class="progress-segment" style="width: 15%; background: #ffae00;">待审核</div>
</div>
</div>
<div class="demo-section">
<h3>圆形进度条</h3>
<div class="circular-progress" style="--progress: 25">
<svg width="100" height="100">
<circle class="bg" cx="50" cy="50" r="45"></circle>
<circle class="meter" cx="50" cy="50" r="45" style="stroke: #cc4b37;"></circle>
</svg>
<span class="value">25%</span>
</div>
<div class="circular-progress" style="--progress: 50">
<svg width="100" height="100">
<circle class="bg" cx="50" cy="50" r="45"></circle>
<circle class="meter" cx="50" cy="50" r="45" style="stroke: #ffae00;"></circle>
</svg>
<span class="value">50%</span>
</div>
<div class="circular-progress" style="--progress: 75">
<svg width="100" height="100">
<circle class="bg" cx="50" cy="50" r="45"></circle>
<circle class="meter" cx="50" cy="50" r="45" style="stroke: #1779ba;"></circle>
</svg>
<span class="value">75%</span>
</div>
<div class="circular-progress" style="--progress: 100">
<svg width="100" height="100">
<circle class="bg" cx="50" cy="50" r="45"></circle>
<circle class="meter" cx="50" cy="50" r="45" style="stroke: #3adb76;"></circle>
</svg>
<span class="value">100%</span>
</div>
</div>
<div class="demo-section">
<h3>动态进度条</h3>
<div class="progress primary" id="dynamic-progress" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
<div class="progress-meter" style="width: 0%"></div>
</div>
<button class="button" onclick="startProgress()">开始加载</button>
<button class="button secondary" onclick="resetProgress()">重置</button>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/foundation-sites@6.7.5/dist/js/foundation.min.js"></script>
<script>
$(document).foundation();
function startProgress() {
var progress = document.getElementById('dynamic-progress');
var meter = progress.querySelector('.progress-meter');
var current = 0;
var interval = setInterval(function() {
current += Math.random() * 10;
if (current > 100) current = 100;
meter.style.width = current + '%';
progress.setAttribute('aria-valuenow', Math.round(current));
if (current >= 100) {
clearInterval(interval);
}
}, 200);
}
function resetProgress() {
var progress = document.getElementById('dynamic-progress');
var meter = progress.querySelector('.progress-meter');
meter.style.width = '0%';
progress.setAttribute('aria-valuenow', 0);
}
</script>
</body>
</html>进度条最佳实践
- 可访问性:使用
role="progressbar"和 ARIA 属性 - 实时更新:对于长时间操作,定期更新进度
- 颜色指示:使用颜色表达进度状态(如接近完成用绿色)
- 文本反馈:为重要进度提供文字说明
- 平滑过渡:使用 CSS transition 使进度变化更平滑
html
<!-- 可访问的进度条 -->
<div class="progress"
role="progressbar"
tabindex="0"
aria-valuenow="75"
aria-valuemin="0"
aria-valuemax="100"
aria-label="文件上传进度">
<div class="progress-meter" style="width: 75%">
<span class="progress-meter-text">75%</span>
</div>
</div>总结
本章我们学习了:
- 基本进度条的创建
- 不同颜色和高度的进度条
- 带文本和动画效果的进度条
- 条纹和堆叠进度条
- 圆形进度条
- JavaScript 动态更新进度
下一章,我们将学习 Foundation 面板。
提示:进度条是用户体验的重要组成部分,它能让用户了解操作的状态,减少等待焦虑。