Accessibility: what can aria-haspopup be used for?
Categories:
Understanding aria-haspopup
: Enhancing Accessibility for Interactive Elements

Explore the purpose and proper usage of the aria-haspopup
attribute to improve accessibility for menus, dialogs, and other pop-up elements in web applications.
In web development, creating accessible user interfaces is paramount. The WAI-ARIA (Web Accessibility Initiative - Accessible Rich Internet Applications) specification provides attributes to help assistive technologies understand the roles and states of dynamic UI components. One such crucial attribute is aria-haspopup
. This article delves into what aria-haspopup
is, its various values, and how to implement it correctly to ensure your interactive elements are accessible to all users.
What is aria-haspopup
?
The aria-haspopup
attribute indicates that an element has a pop-up context menu or sub-level menu. It informs assistive technologies, such as screen readers, that activating the element will trigger the appearance of a pop-up UI element. This is vital for users who cannot visually perceive the pop-up or interact with it directly via a mouse. By using aria-haspopup
, you provide semantic information about the element's behavior, allowing screen readers to announce it appropriately (e.g., "menu button, has pop-up menu").
Values and Their Meanings
aria-haspopup
accepts several enumerated values, each describing a specific type of pop-up. Choosing the correct value is crucial for conveying accurate information to assistive technologies. Misusing these values can lead to a confusing or inaccessible experience for users.
Here's a breakdown of the possible values:
flowchart TD A[Element with `aria-haspopup`] A --> B{Value of `aria-haspopup`?} B -->|`false`| C[No pop-up (default)] B -->|`true` (deprecated)| D[Generic pop-up (use specific values)] B -->|`menu`| E[Menu or sub-menu] B -->|`listbox`| F[Listbox (e.g., custom select)] B -->|`tree`| G[Tree structure (e.g., file explorer)] B -->|`grid`| H[Grid (e.g., spreadsheet-like)] B -->|`dialog`| I[Modal dialog or alert dialog] B -->|`tooltip`| J[Tooltip (rarely used, prefer `aria-describedby`)] E --> K[Example: Navigation menu, context menu] F --> L[Example: Autocomplete suggestions, custom dropdowns] G --> M[Example: Hierarchical navigation] H --> N[Example: Data table with interactive cells] I --> O[Example: Confirmation dialog, settings modal] J --> P[Example: Small, informative pop-up]
Decision tree for aria-haspopup
values
false
(default): The element does not have a pop-up.true
: (Deprecated) Indicates a generic pop-up. It's recommended to use more specific values likemenu
ordialog
instead.menu
: The element opens a menu or sub-menu. This is commonly used for navigation menus, dropdowns, or context menus.listbox
: The element opens a listbox, often used for custom select elements or autocomplete suggestions.tree
: The element opens a tree structure, like a file explorer or hierarchical navigation.grid
: The element opens a grid, such as a spreadsheet-like interface.dialog
: The element opens a modal dialog or an alert dialog. This is crucial for conveying that user interaction is required within the pop-up.tooltip
: (Rarely used) The element opens a tooltip. For simple tooltips,aria-describedby
is often a more appropriate and simpler solution.
Practical Implementation Examples
Let's look at how to apply aria-haspopup
in common scenarios. Remember that aria-haspopup
should be used in conjunction with other ARIA attributes like aria-expanded
to indicate the current state of the pop-up (open or closed) and aria-controls
to link the trigger element to the pop-up content.
role="menu"
, role="dialog"
) and that keyboard navigation is fully supported within the pop-up.<button id="menuButton" aria-haspopup="menu" aria-expanded="false">
Options
</button>
<ul role="menu" aria-labelledby="menuButton" hidden>
<li role="none"><a role="menuitem" href="#">Edit</a></li>
<li role="none"><a role="menuitem" href="#">Delete</a></li>
</ul>
Example of a menu button using aria-haspopup="menu"
<button id="dialogButton" aria-haspopup="dialog" aria-expanded="false">
Open Settings
</button>
<div role="dialog" aria-labelledby="dialogTitle" aria-modal="true" hidden>
<h2 id="dialogTitle">Settings</h2>
<p>Adjust your preferences here.</p>
<button>Close</button>
</div>
Example of a button triggering a dialog using aria-haspopup="dialog"
Common Pitfalls and Best Practices
While aria-haspopup
is powerful, it's easy to misuse. Here are some common mistakes to avoid and best practices to follow:
- Don't use
aria-haspopup
for simple dropdowns that are merelyselect
elements. Native<select>
elements are inherently accessible. - Always pair
aria-haspopup
witharia-expanded
.aria-expanded
tells assistive technologies whether the pop-up is currently visible or hidden. - Ensure keyboard accessibility. Users must be able to open, navigate, and close the pop-up using only the keyboard (e.g., Tab, Shift+Tab, Escape keys).
- Manage focus. When a pop-up opens, focus should typically move into the pop-up. When it closes, focus should return to the triggering element.
- Provide clear visual cues. While ARIA helps screen readers, visual users also benefit from clear indicators that an element will open a pop-up (e.g., a down arrow for menus).
- Test with assistive technologies. The best way to ensure correct implementation is to test your components with actual screen readers (e.g., NVDA, JAWS, VoiceOver).
aria-haspopup="true"
as it is deprecated. Always strive for the most specific value (menu
, dialog
, listbox
, etc.) to provide the richest semantic information.