When you look at a progress bar on a website, you can usually see how far something has gone, maybe a file upload shows “60% complete” or a loading bar fills up before a page is ready. That’s easy to understand if you can see the screen.
But for someone using a screen reader, things work differently. A screen reader announces what’s on the page. If a progress bar isn’t given a proper name, all the person hears is “progress bar, 60%”. The problem? Users who access content through screen readers may not understand what is loading or what task is at 60%. Is it their file? A page? A video?
That’s where accessible names come in.
What is an Accessible Name?
An accessible name is just a label that tells assistive technologies what something is. For a button, it might be “Submit.” For an image, it might be “Company logo.” For a progress bar, it should describe what’s being tracked, like “File upload progress” or “Profile loading.”
This name doesn’t have to be visible text (though it can be). It’s usually provided with ARIA attri butes.
Why Does This Matter?
Without an accessible name, users who rely on screen readers don’t get the context they need. Imagine hearing just “progress bar, 70%”. That could mean anything.
With a name, the experience is much clearer: “File upload progress bar, 70%”. Now the user knows exactly what’s happening.
When Should You Use It?
Every time you add a role=”progressbar” in your code, you need to give it an accessible name. Common places where progress bars appear include:
- File uploads
- Page loaders
- Long-running tasks like “Processing payment” or “Installing updates”
If you’re showing progress to a sighted user, you should assume someone using a screen reader needs that same information.
How Do You Add an Accessible Name?
There are three reliable ways to do this:
Use aria-labelledby
This links the progress bar to an existing piece of text on the page.
<div role="progressbar" aria-labelledby="uploadLabel"></div>
<div id="uploadLabel">File Upload</div>
Here, the screen reader will announce “File Upload progress bar, 60%.”
Use aria-label
This directly gives the progress bar a name, even if there’s no visible label.
<div role="progressbar" aria-label="Loading profile data"></div>
Screen readers will read “Loading profile data, 60%.”
Use title as fallback
The title attribute can also provide a name if other methods aren’t used.
<div role="progressbar" title="Page loading"></div>
Screen readers will announce “Page loading, 60%.”
Examples of What Not to Do
Here are some incorrect patterns and why they fail:
- No name at all → screen reader only says “progress bar.”
<div role="progressbar"></div>
2. Empty label → overrides everything else, but says nothing.
<div role="progressbar" aria-label=""></div>
3. Points to an element that doesn’t exist → name is missing.
<div role="progressbar" aria-labelledby="missingLabel"></div>
<!-- The element with id "missingLabel" does not exist -->
Points to an element that exists, but has no text → still says nothing.
<div role="progressbar" aria-labelledby="emptyDiv"></div>
<div id="emptyDiv"></div>
Fixing the Problems
The fixes are straightforward:
- Add a meaningful aria-label if there’s no visible text.
- Point aria-labelledby to the correct element that has actual text inside.
- Never leave the label empty.
So the last example, fixed, looks like this:
<div role="progressbar" aria-labelledby="statusText"></div>
<div id="statusText">Uploading images</div>
Now the screen reader will announce “Uploading images, 40%.”
Wrapping Up
Accessible names make progress bars useful for everyone. They provide the missing context for users who can’t see the screen but rely on hearing what’s happening.
- Without a name → “progress bar, 60%” (confusing)
- With a name → “File upload progress bar, 60%” (clear and useful)
Always make sure your progress bars have accessible names using aria-labelledby, aria-label, or title. It’s a small change in your code that makes a huge difference in accessibility.