Whether you build a widget as a web component using standards, Vue, React, or any other framework, or with a combination of HTML and JavaScript, screen readers that encounter your widget will look for clues in the rendered markup to discern what it is and tell users that they’ve encountered a search box, menu, or carousel.
Screen readers generally follow this order of precedence:
- Look for explicitly set ARIA attributes (roles, states, properties), and in the absence of those:
- Interpret any implicit roles from markup semantics (form elements, paragraphs, lists, etc).
- Read any text available in the markup.
If no discernable semantics exist (think ARIA-less
<div>
or<span>
tags), it skips to #3. So when you omit ARIA, you’re rolling the dice on whether users will understand that your<ul>
is a menu and not simply a list. When you omit ARIA and semantic tags, you’re leaving it up to your users to figure things out (and potentially abandon your product because it doesn’t work).