Bulma Progress

Bulma Progress bars are flexible components for displaying progress, loading states, or completion percentages. They can be styled with different colors, sizes, and can show text values.

Basic Progress Bar

Simple progress bar with default styling:

<progress class="progress" value="50" max="100">50%</progress>
50%

Progress Bar Colors

Apply color modifiers for different states:

<!-- Primary -->
<progress class="progress is-primary" value="30" max="100">30%</progress>

<!-- Success -->
<progress class="progress is-success" value="60" max="100">60%</progress>

<!-- Warning -->
<progress class="progress is-warning" value="80" max="100">80%</progress>

<!-- Danger -->
<progress class="progress is-danger" value="90" max="100">90%</progress>

<!-- Info -->
<progress class="progress is-info" value="40" max="100">40%</progress>

<!-- Dark -->
<progress class="progress is-dark" value="70" max="100">70%</progress>

<!-- Light -->
<progress class="progress is-light" value="20" max="100">20%</progress>
30%60%80%90%40%

Progress Bar Sizes

<!-- Small -->
<progress class="progress is-small" value="50" max="100">50%</progress>

<!-- Default -->
<progress class="progress" value="50" max="100">50%</progress>

<!-- Medium -->
<progress class="progress is-medium" value="50" max="100">50%</progress>

<!-- Large -->
<progress class="progress is-large" value="50" max="100">50%</progress>
50%50%50%50%

Indeterminate Progress

For loading states where progress isn't measurable:

<progress class="progress" max="100">Loading...</progress>
Loading...

Progress with Text

Display percentage or custom text with progress bar:

<div class="field">
  <label class="label">Upload Progress</label>
  <div class="control">
    <progress class="progress is-primary" value="75" max="100">75%</progress>
  </div>
  <p class="help">75% completed</p>
</div>

<!-- With inline text -->
<div class="level">
  <div class="level-left">
    <div class="level-item">
      <span>Processing files...</span>
    </div>
  </div>
  <div class="level-right">
    <div class="level-item">
      <span class="tag is-info">65%</span>
    </div>
  </div>
</div>
<progress class="progress is-info" value="65" max="100">65%</progress>

Multiple Progress Bars

Stack multiple progress bars for complex status:

<div class="block">
  <p class="heading">Storage Usage</p>
  
  <div class="field">
    <label class="label">Documents</label>
    <progress class="progress is-primary" value="60" max="100">60%</progress>
  </div>
  
  <div class="field">
    <label class="label">Images</label>
    <progress class="progress is-info" value="30" max="100">30%</progress>
  </div>
  
  <div class="field">
    <label class="label">Videos</label>
    <progress class="progress is-success" value="10" max="100">10%</progress>
  </div>
</div>

Animated Progress Bars

Add animation for better UX:

<!-- With CSS animation -->
<style>
.progress.is-animated::-webkit-progress-value {
  transition: width 0.5s ease;
}
.progress.is-animated::-moz-progress-bar {
  transition: width 0.5s ease;
}
</style>

<progress class="progress is-animated is-primary" value="0" max="100" id="animated-progress">0%</progress>

<script>
// Animate progress bar
const progressBar = document.getElementById('animated-progress');
let progress = 0;

const interval = setInterval(() => {
  progress += 10;
  progressBar.value = progress;
  
  if (progress >= 100) {
    clearInterval(interval);
  }
}, 500);
</script>

JavaScript Integration

Dynamically update progress bars:

// Update progress bar value
function updateProgressBar(progressBarId, value, max = 100) {
  const progressBar = document.getElementById(progressBarId);
  progressBar.value = value;
  progressBar.textContent = `${Math.round((value / max) * 100)}%`;
}

// File upload progress
function simulateFileUpload() {
  const progressBar = document.getElementById('upload-progress');
  let progress = 0;
  
  const interval = setInterval(() => {
    progress += Math.random() * 10;
    if (progress > 100) progress = 100;
    
    progressBar.value = progress;
    
    // Update status text
    const status = document.getElementById('upload-status');
    status.textContent = `Uploading: ${Math.round(progress)}%`;
    
    if (progress >= 100) {
      clearInterval(interval);
      status.textContent = 'Upload complete!';
      status.className = 'has-text-success';
    }
  }, 300);
}

// Form completion progress
function calculateFormProgress() {
  const form = document.getElementById('my-form');
  const inputs = form.querySelectorAll('input[required], select[required], textarea[required]');
  const total = inputs.length;
  let filled = 0;
  
  inputs.forEach(input => {
    if (input.value.trim() !== '') {
      filled++;
    }
  });
  
  const progress = Math.round((filled / total) * 100);
  updateProgressBar('form-progress', progress);
}

// Add event listeners to form inputs
document.querySelectorAll('#my-form input, #my-form select, #my-form textarea').forEach(input => {
  input.addEventListener('input', calculateFormProgress);
  input.addEventListener('change', calculateFormProgress);
});

Practical Examples

File Upload Progress

<div class="box">
  <div class="media">
    <div class="media-left">
      <span class="icon is-large">
        <i class="fas fa-2x fa-file-pdf"></i>
      </span>
    </div>
    <div class="media-content">
      <div class="content">
        <p>
          <strong>document.pdf</strong>
          <br>
          <small>12.5 MB</small>
        </p>
      </div>
      
      <div class="field">
        <progress class="progress is-primary" value="65" max="100" id="upload-progress">65%</progress>
        <p class="help" id="upload-status">Uploading: 65%</p>
      </div>
    </div>
    <div class="media-right">
      <button class="button is-text">Cancel</button>
    </div>
  </div>
</div>

Onboarding Progress

<div class="box">
  <h3 class="title is-4">Complete Your Profile</h3>
  <p class="subtitle is-6">Step 3 of 5</p>
  
  <progress class="progress is-primary" value="60" max="100">60%</progress>
  
  <div class="level is-mobile">
    <div class="level-left">
      <div class="level-item">
        <span class="icon has-text-success"><i class="fas fa-check-circle"></i></span>
        <span>Account Created</span>
      </div>
    </div>
    <div class="level-item">
      <span class="icon has-text-success"><i class="fas fa-check-circle"></i></span>
      <span>Email Verified</span>
    </div>
    <div class="level-item">
      <span class="icon has-text-primary"><i class="fas fa-user-circle"></i></span>
      <span>Profile Info</span>
    </div>
    <div class="level-item">
      <span class="icon"><i class="far fa-circle"></i></span>
      <span>Preferences</span>
    </div>
    <div class="level-right">
      <div class="level-item">
        <span class="icon"><i class="far fa-circle"></i></span>
        <span>Complete</span>
      </div>
    </div>
  </div>
</div>

Project Completion Status

<div class="card">
  <div class="card-content">
    <div class="media">
      <div class="media-content">
        <p class="title is-5">Website Redesign</p>
        <p class="subtitle is-6">Due: Dec 30, 2024</p>
      </div>
      <div class="media-right">
        <span class="tag is-primary">75%</span>
      </div>
    </div>
    
    <div class="content">
      <progress class="progress is-primary" value="75" max="100">75%</progress>
      
      <div class="level is-mobile">
        <div class="level-item has-text-centered">
          <div>
            <p class="heading">Tasks</p>
            <p class="title">12/16</p>
          </div>
        </div>
        <div class="level-item has-text-centered">
          <div>
            <p class="heading">Days Left</p>
            <p class="title">15</p>
          </div>
        </div>
        <div class="level-item has-text-centered">
          <div>
            <p class="heading">Team</p>
            <p class="title">4</p>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Multi-step Form Progress

<div class="steps" id="steps">
  <div class="step-item is-active is-success">
    <div class="step-marker">
      <span class="icon"><i class="fas fa-user"></i></span>
    </div>
    <div class="step-details">
      <p class="step-title">Personal</p>
    </div>
  </div>
  <div class="step-item is-active">
    <div class="step-marker">2</div>
    <div class="step-details">
      <p class="step-title">Address</p>
    </div>
  </div>
  <div class="step-item">
    <div class="step-marker">3</div>
    <div class="step-details">
      <p class="step-title">Payment</p>
    </div>
  </div>
  <div class="step-item">
    <div class="step-marker">4</div>
    <div class="step-details">
      <p class="step-title">Confirm</p>
    </div>
  </div>
</div>

<div class="block">
  <progress class="progress is-primary" value="50" max="100">50%</progress>
  <p class="has-text-centered is-size-7">Step 2 of 4</p>
</div>

Best Practices

  • Always include a label or context for what the progress bar represents
  • Use appropriate colors: primary for normal, success for completion, warning for nearing limits, danger for errors
  • Show percentage or status text alongside the progress bar
  • Use indeterminate progress bars for unknown duration operations
  • Consider adding animation for better user experience
  • Make progress bars accessible with proper ARIA labels
  • Update progress bars smoothly with JavaScript animations
Accessibility: Add aria-valuenow, aria-valuemin, and aria-valuemax attributes for screen readers, and provide a text alternative within the progress element.

Next: Bulma Section Component