Skip to content

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>

进度条最佳实践

  1. 可访问性:使用 role="progressbar" 和 ARIA 属性
  2. 实时更新:对于长时间操作,定期更新进度
  3. 颜色指示:使用颜色表达进度状态(如接近完成用绿色)
  4. 文本反馈:为重要进度提供文字说明
  5. 平滑过渡:使用 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 面板


提示:进度条是用户体验的重要组成部分,它能让用户了解操作的状态,减少等待焦虑。