Most of the roles you see were defined as part of ARIA 1.0, and then later incorporated into HTML via supporting specs like HTML-AAM. Some of the new HTML5 elements (dialog, main, etc.) are even based on the original ARIA roles.
http://www.w3.org/TR/wai-aria/
There are a few primary reasons to use roles in addition to your native semantic element.
Reason #1. Overriding the role where no host language element is appropriate or, for various reasons, a less semantically appropriate element was used.
In this example, a link was used, even though the resulting functionality is more button-like than a navigation link.
<a href="#" role="button" aria-label="Delete item 1">Delete</a> <!-- Note: href="#" is just a shorthand here, not a recommended technique. Use progressive enhancement when possible. -->
Screen readers users will hear this as a button (as opposed to a link), and you can use a CSS attribute selector to avoid class-itis and div-itis.
[role="button"] { /* style these as buttons w/o relying on a .button class */ }
[Update 7 years later: removed the * selector to make some commenters happy, since the old browser quirk that required universal selector on attribute selectors is unnecessary in 2020.]
Reason #2. Backing up a native element’s role, to support browsers that implemented the ARIA role but haven’t yet implemented the native element’s role.
For example, the “main” role has been supported in browsers for many years, but it’s a relatively recent addition to HTML5, so many browsers don’t yet support the semantic for <main>
.
<main role="main">…</main>
This is technically redundant, but helps some users and doesn’t harm any. In a few years, this technique will likely become unnecessary for main.
Reason #3. Update 7 years later (2020): As at least one commenter pointed out, this is now very useful for custom elements, and some spec work is underway to define the default accessibility role of a web component. Even if/once that API is standardized, there may be need to override the default role of a component.
Note/Reply
You also wrote:
I see some people make up their own. Is that allowed or a correct use of the role attribute?
That’s an allowed use of the attribute unless a real role is not included. Browsers will apply the first recognized role in the token list.
<span role="foo link note bar">...</a>
Out of the list, only link
and note
are valid roles, and so the link role will be applied in the platform accessibility API because it comes first. If you use custom roles, make sure they don’t conflict with any defined role in ARIA or the host language you’re using (HTML, SVG, MathML, etc.)