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 likemenuordialoginstead.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-describedbyis 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-haspopupfor simple dropdowns that are merelyselectelements. Native<select>elements are inherently accessible. - Always pair
aria-haspopupwitharia-expanded.aria-expandedtells 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.