HTML Guide
The role
attribute value navigation
is invalid for a ul
element, as it should be used with a nav
element or similar suitable elements.
In HTML, the role
attribute defines what an element represents in the context of accessible web technologies, primarily for assistive tools like screen readers. The nav
element represents a section of a page intended for navigational links, and it inherently provides the role of navigation
. If you want to make a ul
element serve as navigation, it is more appropriate to use it inside a nav
element, or alternatively, set a valid ARIA role on the element itself.
Detailed Explanation
HTML5 introduced a specific set of elements with implicit ARIA roles and behaviors, like the nav
element, which implicitly has the navigation
role. For backward compatibility or advanced use cases, developers might explicitly set ARIA roles using the role
attribute. However, setting an invalid role can lead to accessibility issues, as seen with trying to assign navigation
to a ul
element.
Instead of applying the navigation
role to a ul
directly, wrap your ul
with a nav
element.
The allowed ARIA roles for an ul
element are directory
, group
, listbox
, menu
, menubar
, none
, presentation
, radiogroup
, tablist
, toolbar
and tree
, but not navigation
.
Examples
Here is how you can use the nav
element with a ul
.
<nav>
<ul>
<li><a href="#home">Home</a></li>
<li><a href="#about">About</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</nav>
Learn more:
Related W3C validator issues
The role attribute in HTML is used to define the accessibility role of an element, which helps assistive technologies understand the purpose or type of the element. The value tabpanel is not appropriate for a <ul> element, which is used for unordered lists.
The role of tabpanel is intended to be used with elements that represent a tab panel, which is part of a tabbed interface. A tabbed interface consists of elements with roles like tablist, tab, and tabpanel. Typically, tabpanel is used with containers that house the content associated with a tab, such as a <div>.
To fix this error, ensure that the tabpanel role is applied to the correct element. Here’s a simple example of how a tab interface can be structured correctly:
<div role="tablist" aria-label="Sample Tabs">
<button role="tab" aria-controls="panel-1" id="tab-1">Tab 1</button>
<button role="tab" aria-controls="panel-2" id="tab-2">Tab 2</button>
</div>
<div role="tabpanel" id="panel-1" aria-labelledby="tab-1" hidden>
<p>Content for Tab 1.</p>
</div>
<div role="tabpanel" id="panel-2" aria-labelledby="tab-2" hidden>
<p>Content for Tab 2.</p>
</div>
In this example:
- The role tablist is applied to the container element that directly contains the tab elements.
- Each button serving as a tab has the role of tab.
- Each tab panel, which contains the content for a tab, has the role of tabpanel.
Avoid using tabpanel on non-semantic or incorrectly associated elements like <ul>. Instead, use elements like <div> or <section> for tab panels, ensuring the roles align with the intended roles in a tabbed interface.
The alert role can be used to tell the user an element has been dynamically updated. Screen readers will instantly start reading out the updated content when the role is added. The element <ul> doesn’t accept this kind of role, consider using other element like <p> or <div>.
The alert role is used to communicate an important and usually time-sensitive message to the user. When this role is added to an element, the browser will send out an accessible alert event to assistive technology products which can then notify the user about it. The alert role is most useful for information that requires the user’s immediate attention.
The dialog element does not require or permit a role="dialog" attribute according to HTML standards.
The <dialog> element has an implicit ARIA role of dialog, so adding role="dialog" is redundant and not valid per the specification. Instead, simply use the <dialog> element without an explicit role attribute.
Details:
According to the WHATWG HTML standard and ARIA specification, native <dialog> elements automatically have the correct role. Adding role="dialog" can cause HTML validation errors, as the validator interprets this as a misuse or redundancy.
Correct usage:
<dialog>
<p>This is a dialog box.</p>
<button>Close</button>
</dialog>
Incorrect usage (causes validation error):
<dialog role="dialog">
<p>This is a dialog box.</p>
<button>Close</button>
</dialog>
Removing the role="dialog" attribute resolves the W3C validation issue while maintaining accessibility.
The icon value for attribute role is not a valid ARIA role.
ARIA Roles: Overview
ARIA roles are used to enhance accessibility by clearly defining the role and purpose of an element for assistive technologies. However, there are defined roles that you need to adhere to:
- Standard roles include button, checkbox, alert, dialog, img, etc.
- There is no ARIA role named icon.
Solution
To fix the issue, you need to use a valid ARIA role that accurately describes the purpose of the span element. If your intention is to convey that the span contains an icon, you might want to reconsider whether you need a role at all. Often, purely decorative elements should not have a role, or you might use an img role if it conveys a meaningful image.
Here’s how you can address this:
-
No ARIA role (if purely decorative): If the icon is purely decorative and does not add meaningful content to your page, you should remove the role attribute entirely.
<span class="icon"></span>
-
Using img role (if it represents an image): If the span represents an image or an icon that conveys meaningful information, you can use role="img" and provide a proper aria-label.
<span class="icon" role="img" aria-label="Icon Description"></span>
-
Using an appropriate role (if interactive): If the icon is part of an interactive element, you might need a different role. For instance, if the icon is inside a button:
<button> <span class="icon" aria-hidden="true"></span> Button text </button>
Here, aria-hidden="true" is used to hide the decorative icon from screen readers as the text provides the necessary context.
Use role="none" (or remove the role) instead of role="presentation" on an img.
The role attribute maps elements to ARIA roles. For images, the valid way to make an image decorative is to either omit the ARIA role and use an empty alt attribute (alt=""), or use the ARIA role none. In ARIA 1.1, role="none" and role="presentation" are equivalent, but the W3C HTML Validator flags role="presentation" on img because the correct, accessible pattern is an empty alt to hide the image from assistive tech. Use alt="" alone, or pair it with role="none" if you need an explicit ARIA role. If the image conveys meaning, provide a descriptive alt and no role.
HTML Examples
Example that reproduces the issue
<img src="avatar.png" alt="" role="presentation">
Fixed examples
Decorative image (preferred minimal fix):
<img src="avatar.png" alt="">
Informative image:
<img src="chart.png" alt="Quarterly sales trend line chart">
Remove the role="list" attribute from the ul element.
The ul (unordered list) element is inherently recognized as a list in HTML. As such, it is automatically associated with the semantic role of a list. Adding role="list" to a ul is redundant and can also confuse browsers and screen readers, potentially leading to inconsistent behavior or impaired accessibility. This attribute is unnecessary because the list role is implicitly defined for this element through HTML specifications, and W3C HTML validation flags it to ensure semantic clarity and best practices.
Example of Incorrect role Usage:
<ul role="list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
Corrected Example Without Unnecessary role:
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
By excluding the role="list", the code adheres to semantic clarity and best practices, complying with W3C standards while maintaining accessibility.
The navigation landmark role is used to identify major groups of links used for navigating through a website or page content. It can be added to an element that contains navigation links by using role="navigation", but instead it’s preferable to just use the <nav> element. In that case, it’s unnecessary to make the navigation role explicit.
Examples:
<div role="navigation">
<!-- this is a valid way to define a navigation role -->
</div>
<nav>
<!-- but this is shorter and uses correct semantic HTML -->
</nav>
There can only be one visible <main> element in a document. If more are needed (for example for switching between them with JavaScript), only one can be visible, the others should be hidden toggling the hidden attribute.
Example of 2 main elements, where only one is visible:
<main>
<h1>Active main element</h1>
<!-- content -->
</main>
<main hidden>
<h1>Hidden main element</h1>
<!-- content -->
</main>
The HTML <figure> element is used to encapsulate media content, such as an image or graphic, along with a descriptive <figcaption>. When a <figcaption> is present within a <figure>, it inherently provides the semantics of the <figure>, making it self-explanatory without needing an additional role attribute.
Explanation
-
<figure> element: Represents self-contained content, potentially with an optional caption specified by a <figcaption> element. This is inherently recognized for its semantics as a figure with a caption.
-
<figcaption> element: Provides a caption or description for the content of the <figure>. This helps in describing the media or content included in the <figure> element.
-
role attribute: This attribute is used to define an explicit accessibility role for an element. However, in cases where the element’s native semantics are explicit and sufficient, such as a <figure> with a <figcaption>, adding a role attribute might override or conflict with the inherent meaning.
Solution
Remove the role attribute from the <figure> element when it contains a <figcaption>.
Example of Incorrect Code:
<figure role="figure">
<img src="cat.jpg" alt="A cute cat">
<figcaption>A cute cat looking at the camera.</figcaption>
</figure>
Corrected Code:
<figure>
<img src="cat.jpg" alt="A cute cat">
<figcaption>A cute cat looking at the camera.</figcaption>
</figure>
In the corrected example, the <figure> element does not have a role attribute, allowing it to maintain its inherent semantic value.
A role="cell" element must be a child of an element with role="row" for correct ARIA relationships.
According to the ARIA specification, role="cell" should be directly contained within a parent with role="row", which itself should usually be inside an element with role="rowgroup" or role="table". This structure allows assistive technologies to interpret your table semantics correctly.
Correct Structure Example:
<div role="table">
<div role="row">
<div role="cell">Row 1, Cell 1</div>
<div role="cell">Row 1, Cell 2</div>
</div>
<div role="row">
<div role="cell">Row 2, Cell 1</div>
<div role="cell">Row 2, Cell 2</div>
</div>
</div>
Incorrect Structure Example (missing row):
<div role="table">
<div role="cell">Cell without row</div>
</div>
How to fix:
Wrap any element with role="cell" inside an element with role="row". This ensures both validity and proper accessibility support.