Why mark up a menu of links as a <ul> of <li> elements instead of a stack of <a> elements inside a <div>, and what do screen reader users lose in the second version?
answer
- the layout communicates something the text does not
- implicit roles arrive with the element
- count, position, and where the group ends
- nesting level for submenus
- native element before any role attribute
basics
~20 sA <ul> carries the implicit ARIA role list and each <li> carries listitem, so assistive tech announces how many links there are, each link's position in the set, and where the group ends. A stack of <a> elements in a <div> conveys none of that.
solid answer
~50 sWrapping the links in `<ul>`/`<li>` turns a visual grouping into a machine-readable one. `<ul>` and `<ol>` have the implicit ARIA role `list` and `<li>` has `listitem`, so a screen reader announces something like "list, six items" on entry, gives each link a position within the set as the user moves through it, and signals when the group ends. It also reports nesting level for submenus, so a user knows they have stepped into a sub-group. In the `<div>` version the links are just six unrelated things in a row: no count, no sense of progress, no boundary. Sighted users get all of that for free from the layout — the spacing, the alignment, the fact the block visibly ends. The list markup is how you give the same information to someone who cannot see the layout, and it costs one wrapper element.
code
html · 9 lines<ul class="menu">
<li><a href="/">Home</a></li>
<li><a href="/pricing">Pricing</a></li>
<li><a href="/docs">Docs
<ul>
<li><a href="/docs/api">API</a></li>
</ul>
</li>
</ul>go deeper
Be able to say that <ul> and <li> group links into a real set, and write a menu that way by default rather than as bare links in a div.
Name the implicit roles list and listitem and describe concretely what they buy: an item count on entry, position within the set, a boundary at the end, and nesting level for submenus.
Argue the tradeoff under design pressure — defend the extra element, explain why hand-rolled ARIA roles are the worse option, and connect the choice to how users actually navigate by skipping groups.
Turn the principle into a standard: any meaning the visual design carries must exist in markup too, and make that reviewable so component libraries ship the structure rather than leaving each team to rediscover it.
## The information the layout is already carrying Look at a rendered menu and you learn several things without reading a word: these items belong together, there are roughly this many of them, this one is the third, and the group stops here. None of that is in the text; it comes from the visual arrangement. A screen reader user does not receive the arrangement. They receive the accessibility tree, which is built from the *elements* you chose. If the only element you chose is a `<div>` — which has no semantics at all — then the grouping simply does not exist for them. ## What the list elements contribute `<ul>` and `<ol>` have the implicit ARIA role `list`; `<li>` has the implicit role `listitem`. From that pair, assistive technology derives three things: - **A count on entry.** Screen readers typically announce the list and its size, along the lines of "list, six items", so the user knows the size of what they are about to traverse. - **A position within the set.** As the user moves item by item, they hear where they are — the sense of progress a sighted user gets from the scrollbar and the layout. - **A boundary.** Leaving the list is announced, so the user knows the group ended rather than wondering whether the next link is still part of the menu. Nesting adds a fourth: a sublist inside an `<li>` is reported as a deeper level, which is how a submenu reads as belonging to its parent item. ```html <!-- semantics-free: six things in a row --> <div class="menu"> <a href="/">Home</a> <a href="/pricing">Pricing</a> </div> <!-- a group with a size, positions, and an end --> <ul class="menu"> <li><a href="/">Home</a></li> <li><a href="/pricing">Pricing</a></li> </ul> ``` ## Why the native element rather than ARIA The first rule of ARIA is not to use ARIA when a native element already does the job. You *could* write `<div role="list">` with `<div role="listitem">` children and get comparable exposure, but you would be re-declaring in attributes what two elements give you for free, and any typo silently produces a broken structure — a `listitem` whose parent is not a list, for instance. The native elements cannot get out of sync with themselves. The one legitimate case for the explicit roles is restoring semantics a stylesheet removed, which is a repair, not a design. ## The usual objections, answered *"It adds a wrapper element per link."* It does, and that is the entire cost. Modern layout does not need the extra element removed — a list is perfectly capable of being laid out horizontally. *"Our design has no bullets."* Bullets are the marker, not the semantics; removing them is a styling choice and does not change what the element means. (Note the one browser wrinkle: in Safari, suppressing markers can make VoiceOver stop treating it as a list, which is repaired with an explicit `role="list"`.) *"Screen readers announce more, which is noise."* Users can and do skip lists wholesale; the count is what lets them decide to. Removing the structure does not reduce noise, it removes the ability to navigate past it. ## Where the reasoning generalises The same argument decides many markup questions: if a visual property of your design communicates something — grouping, order, count, hierarchy, importance — then that meaning must also exist in the markup, or it exists only for people who can see the screen. A list is the cheapest instance of the rule. Related instances are headings for hierarchy, an ordered list where sequence matters, and a description list where items are name/value pairs. ## Getting the details right Put exactly one interactive element per item where you can, keep the `<a>` inside the `<li>` rather than the other way round (an `<a>` cannot contain an `<li>`), and if a submenu is present, nest it inside the parent `<li>`. Do not add `role="list"` and `role="listitem"` on top of real list elements as a matter of habit — redundant roles are harmless but signal that the author does not trust the native semantics, and an interviewer will notice.
- Could you get the same exposure with <div role="list"> and <div role="listitem">?Broadly yes, and that is exactly why you should not. The native elements give the same roles with no attributes to misspell and no risk of a `listitem` ending up outside a `list`. ARIA's first rule is to prefer the native element; hand-rolled roles are justified only when repairing semantics something else removed.
- Does a single link need to be wrapped in a list?No. A list communicates that items form a set with a size, and a one-item set carries almost no information while still costing the user a "list, one item" announcement. Wrap links in a list when there are several of them and their grouping is meaningful; a lone link is just a link.
- What does nesting a submenu inside its parent <li> add over placing it after that item?Ownership and level. Nested inside, assistive tech reports the sublist as a deeper level belonging to the parent item, which mirrors what the indentation shows visually. Placed after the item, it is a separate list at the same level and the parent-child relationship is lost entirely.
The div version is a pile of loose index cards; the list version is the same cards in a numbered box that tells you how many are inside.
saying these in an interview costs you the question
- Says lists are only for bullet points
- Claims a div with classes is equivalent if it looks the same
- Reaches for role="list" on divs instead of using ul
- Thinks removing bullets removes list semantics generally
- Believes screen readers infer grouping from CSS layout