Skip to content

Foundation Progress Bars

Foundation progress bars are used to display the progress of task completion or status. This chapter will introduce various uses of Foundation progress bars.

Basic Progress Bar

Use .progress and .progress-meter to create basic progress bars:

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>

Different Progress Values

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>

Progress Bar Colors

Foundation provides multiple color options:

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>

Color Usage Guide

ClassColorCommon Use
.primaryBlueDefault progress
.secondaryGraySecondary progress
.successGreenSuccess/Complete
.warningYellowWarning/Attention
.alertRedDanger/Error

Progress Bars with Text

Display text inside the progress bar:

html
<div class="progress" role="progressbar" tabindex="0">
    <span class="progress-meter" style="width: 50%">
        <p class="progress-meter-text">50%</p>
    </span>
</div>

Text at Different Positions

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% Complete</span>
</div>

Native HTML5 Progress Bar

Foundation also supports native <progress> elements:

html
<progress max="100" value="75"></progress>

Styling Native Progress Bars

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>

Striped Progress Bar

Add striped effect:

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>

Animated Progress Bar

Add animation effect:

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>

Progress Bar Height

Customize progress bar height:

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>

Stacked Progress Bar

Display multiple values in one progress bar:

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;">Completed 30%</div>
    <div class="progress-segment" style="width: 20%; background: #1779ba;">In Progress 20%</div>
    <div class="progress-segment" style="width: 15%; background: #ffae00;">Pending 15%</div>
</div>

Circular Progress Bar

Use SVG to create circular progress bars:

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>

Progress Bars with Labels

Combine with labels to display status:

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">Complete</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 Dynamic Update

Basic Update

javascript
function updateProgress(element, value) {
    var meter = element.querySelector('.progress-meter');
    meter.style.width = value + '%';

    // Update ARIA attributes
    element.setAttribute('aria-valuenow', value);

    // If there's text, update it
    var text = meter.querySelector('.progress-meter-text');
    if (text) {
        text.textContent = value + '%';
    }
}

// Usage
var progressBar = document.querySelector('.progress');
updateProgress(progressBar, 75);

Simulating Loading Progress

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);
}

// Complete within 5 seconds
simulateProgress(document.querySelector('.progress'), 5000);

Complete Example

html
<!DOCTYPE html>
<html class="no-js" lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Foundation Progress Bars Example</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 Progress Bars Showcase</h1>

        <div class="demo-section">
            <h3>Basic Progress Bars</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>Different Colors</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>Progress Bars with Text</h3>
            <div class="progress thick primary progress-with-label">
                <span class="progress-meter" style="width: 65%"></span>
                <span class="progress-label">65% Complete</span>
            </div>
        </div>

        <div class="demo-section">
            <h3>Different Heights</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>Striped Progress Bars</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>Animated Progress Bars</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>Stacked Progress Bar</h3>
            <div class="progress-stacked">
                <div class="progress-segment" style="width: 35%; background: #3adb76;">Completed</div>
                <div class="progress-segment" style="width: 25%; background: #1779ba;">In Progress</div>
                <div class="progress-segment" style="width: 15%; background: #ffae00;">Pending</div>
            </div>
        </div>

        <div class="demo-section">
            <h3>Circular Progress Bars</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>Dynamic Progress Bar</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()">Start Loading</button>
            <button class="button secondary" onclick="resetProgress()">Reset</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>

Progress Bar Best Practices

  1. Accessibility: Use role="progressbar" and ARIA attributes
  2. Real-time Updates: Update progress regularly for long operations
  3. Color Indication: Use colors to express progress status (green when close to completion)
  4. Text Feedback: Provide text descriptions for important progress
  5. Smooth Transitions: Use CSS transition for smoother progress changes
html
<!-- Accessible progress bar -->
<div class="progress"
     role="progressbar"
     tabindex="0"
     aria-valuenow="75"
     aria-valuemin="0"
     aria-valuemax="100"
     aria-label="File upload progress">
    <div class="progress-meter" style="width: 75%">
        <span class="progress-meter-text">75%</span>
    </div>
</div>

Summary

In this chapter, we learned:

  • Creating basic progress bars
  • Progress bars with different colors and heights
  • Progress bars with text and animation effects
  • Striped and stacked progress bars
  • Circular progress bars
  • JavaScript dynamic progress updates

Next chapter, we will learn Foundation Panels.


Tip: Progress bars are an important part of user experience. They let users know the status of operations and reduce waiting anxiety.

Content is for learning and research only.