Code examples

There are many variations of progressbars, some of which may not need to be a true progress bar at all.

Support varies by screen reader. It’s recommended to add full aria attributes, even when using a native <progressbar> element.

Use semantic HTML

This semantic HTML contains all accessibility features by default.

<progress role="progressbar"
          id="progress"
          class="progress"
          aria-label="File upload"
          value="25"
          aria-valuemin="0"
          aria-valuenow="25"
          aria-valuemax="100"
          max="100">
  25%
</progress>
25%

Inline dynamic loading waiting example

This example dynamically injects progress updates that will be read by a screen reader

  • aria-busy="true" has spotty support, but does indicate that the region is busy
  • aria-describedby is allows the current progress to be read when the button is focused
  • aria-disabled reinforces that the save action is incomplete
  • role="status has an implicit aria-live=”polite” of polite and aria-atomic="true" meaning the entire content of the status will be read on each update
<div 
  id="slow-app"
  aria-live="polite">
  
  <button 
    id="trigger-progressbar"
    aria-describedby="progress-busy"
    aria-disabled="false">
      Save
  </button>

  <div class="progress-busy inert" role="status">
    <span id="progress-busy">
    </span> 
  </div>
</div>

Developer notes

Name

  • Use aria-label="Progress bar name" when there is not a visible title.

Role

  • Use role="progressbar

Group

  • If the progress bar is describing another region of the page, use aria-describedby="progressbar-id" to connect the two elements.

State

  • The state will be read out to the screen reader user by default.

Focus

  • Progress bar is not usually focusable.