Bootstrap 5 Framework

Progress Bars and Spinners

12 min Lesson 28 of 40

Progress Bars and Spinners in Bootstrap 5

Progress bars and spinners are essential components for indicating loading states and operation progress. They provide visual feedback to users during asynchronous operations.

Basic Progress Bars

Create simple progress bars to show completion percentage:

<!-- Basic Progress Bar --> <div class="progress"> <div class="progress-bar" role="progressbar" style="width: 25%;" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div> </div> <!-- Different Values --> <div class="progress mb-3"> <div class="progress-bar" role="progressbar" style="width: 0%;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div> </div> <div class="progress mb-3"> <div class="progress-bar" role="progressbar" style="width: 50%;" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100"></div> </div> <div class="progress mb-3"> <div class="progress-bar" role="progressbar" style="width: 75%;" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100"></div> </div> <div class="progress"> <div class="progress-bar" role="progressbar" style="width: 100%;" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"></div> </div>
Progress Bar Structure:
  • .progress - Container wrapper
  • .progress-bar - The actual bar
  • role="progressbar" - Accessibility attribute
  • aria-* attributes - For screen readers
  • Width set via inline style or JavaScript

Labeled Progress Bars

Add text labels to show progress percentage:

<!-- Label Inside Bar --> <div class="progress"> <div class="progress-bar" role="progressbar" style="width: 25%;" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100">25%</div> </div> <!-- Label with Minimum Width --> <div class="progress"> <div class="progress-bar" role="progressbar" style="width: 10%; min-width: 2em;" aria-valuenow="10" aria-valuemin="0" aria-valuemax="100">10%</div> </div> <!-- External Label --> <div class="d-flex justify-content-between mb-1"> <span>Progress</span> <span>60%</span> </div> <div class="progress"> <div class="progress-bar" role="progressbar" style="width: 60%;" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100"></div> </div>

Colored Progress Bars

Use contextual background classes to color progress bars:

<div class="progress mb-3"> <div class="progress-bar bg-success" role="progressbar" style="width: 25%" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div> </div> <div class="progress mb-3"> <div class="progress-bar bg-info" role="progressbar" style="width: 50%" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100"></div> </div> <div class="progress mb-3"> <div class="progress-bar bg-warning" role="progressbar" style="width: 75%" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100"></div> </div> <div class="progress"> <div class="progress-bar bg-danger" role="progressbar" style="width: 100%" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"></div> </div>

Multiple Progress Bars

Stack multiple progress bars to show different segments:

<div class="progress"> <div class="progress-bar" role="progressbar" style="width: 15%" aria-valuenow="15" aria-valuemin="0" aria-valuemax="100"></div> <div class="progress-bar bg-success" role="progressbar" style="width: 30%" aria-valuenow="30" aria-valuemin="0" aria-valuemax="100"></div> <div class="progress-bar bg-info" role="progressbar" style="width: 20%" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100"></div> </div> <!-- Labeled Multiple Bars --> <div class="progress"> <div class="progress-bar" role="progressbar" style="width: 35%" aria-valuenow="35" aria-valuemin="0" aria-valuemax="100">HTML 35%</div> <div class="progress-bar bg-success" role="progressbar" style="width: 25%" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100">CSS 25%</div> <div class="progress-bar bg-warning" role="progressbar" style="width: 15%" aria-valuenow="15" aria-valuemin="0" aria-valuemax="100">JS 15%</div> </div>
Tip: Multiple progress bars are great for showing composition or segmented progress, such as file upload chunks or project completion by category.

Striped and Animated Progress Bars

Add stripes and animations to progress bars:

<!-- Striped Progress Bar --> <div class="progress mb-3"> <div class="progress-bar progress-bar-striped" role="progressbar" style="width: 50%" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100"></div> </div> <!-- Animated Striped Progress Bar --> <div class="progress mb-3"> <div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: 75%" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100"></div> </div> <!-- Colored Animated Progress Bar --> <div class="progress"> <div class="progress-bar progress-bar-striped progress-bar-animated bg-success" role="progressbar" style="width: 60%" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100"></div> </div>

Progress Bar Heights

Customize the height of progress bars:

<!-- Thin Progress Bar --> <div class="progress mb-3" style="height: 5px;"> <div class="progress-bar" role="progressbar" style="width: 25%;" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div> </div> <!-- Default Height (1rem / 16px) --> <div class="progress mb-3"> <div class="progress-bar" role="progressbar" style="width: 50%;" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100"></div> </div> <!-- Thick Progress Bar --> <div class="progress" style="height: 30px;"> <div class="progress-bar" role="progressbar" style="width: 75%;" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100">75%</div> </div>

Border Spinner

The border spinner is a lightweight loading indicator:

<!-- Basic Border Spinner --> <div class="spinner-border" role="status"> <span class="visually-hidden">Loading...</span> </div> <!-- Colored Spinners --> <div class="spinner-border text-primary" role="status"> <span class="visually-hidden">Loading...</span> </div> <div class="spinner-border text-success" role="status"> <span class="visually-hidden">Loading...</span> </div> <div class="spinner-border text-danger" role="status"> <span class="visually-hidden">Loading...</span> </div> <div class="spinner-border text-warning" role="status"> <span class="visually-hidden">Loading...</span> </div> <div class="spinner-border text-info" role="status"> <span class="visually-hidden">Loading...</span> </div>

Growing Spinner

The growing spinner repeatedly grows and fades:

<!-- Basic Growing Spinner --> <div class="spinner-grow" role="status"> <span class="visually-hidden">Loading...</span> </div> <!-- Colored Growing Spinners --> <div class="spinner-grow text-primary" role="status"> <span class="visually-hidden">Loading...</span> </div> <div class="spinner-grow text-success" role="status"> <span class="visually-hidden">Loading...</span> </div> <div class="spinner-grow text-danger" role="status"> <span class="visually-hidden">Loading...</span> </div>
Spinner Accessibility: Always include <span class="visually-hidden">Loading...</span> for screen readers, as spinners are purely visual indicators.

Spinner Sizes

Control spinner sizes with sizing classes:

<!-- Small Spinners --> <div class="spinner-border spinner-border-sm" role="status"> <span class="visually-hidden">Loading...</span> </div> <div class="spinner-grow spinner-grow-sm" role="status"> <span class="visually-hidden">Loading...</span> </div> <!-- Custom Size with Inline Styles --> <div class="spinner-border" style="width: 3rem; height: 3rem;" role="status"> <span class="visually-hidden">Loading...</span> </div> <div class="spinner-grow" style="width: 3rem; height: 3rem;" role="status"> <span class="visually-hidden">Loading...</span> </div>

Spinners in Buttons

Use spinners in buttons to indicate loading states:

<!-- Spinner with Text --> <button class="btn btn-primary" type="button" disabled> <span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Loading... </button> <!-- Spinner Only --> <button class="btn btn-primary" type="button" disabled> <span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> <span class="visually-hidden">Loading...</span> </button> <!-- Growing Spinner in Button --> <button class="btn btn-success" type="button" disabled> <span class="spinner-grow spinner-grow-sm" role="status" aria-hidden="true"></span> Processing... </button>
Button Spinner Tips:
  • Always disable the button when showing a loading state
  • Use .spinner-border-sm or .spinner-grow-sm in buttons
  • Include loading text or visually-hidden text for accessibility
  • Consider using JavaScript to toggle spinner visibility

Alignment and Placement

Use flexbox and text utilities to align spinners:

<!-- Center Aligned --> <div class="d-flex justify-content-center"> <div class="spinner-border" role="status"> <span class="visually-hidden">Loading...</span> </div> </div> <!-- Text Aligned --> <div class="text-center"> <div class="spinner-border" role="status"> <span class="visually-hidden">Loading...</span> </div> </div> <!-- Float Right --> <div class="clearfix"> <div class="spinner-border float-end" role="status"> <span class="visually-hidden">Loading...</span> </div> </div>

Practice Exercise

Create a file upload interface with:

  1. A progress bar showing upload percentage (with label)
  2. Multiple colored progress bars showing different file types
  3. An animated striped progress bar for active uploads
  4. A submit button that shows a spinner when clicked
  5. A centered loading spinner for the initial page load
Best Practices:
  • Use progress bars for determinate progress (known duration)
  • Use spinners for indeterminate progress (unknown duration)
  • Always include aria attributes for accessibility
  • Disable interactive elements during loading states
  • Provide clear visual feedback for all async operations
  • Consider using animated progress bars for better UX