Product A
$49.99
Semantic lists, card groups, and ARIA for collections
When you have multiple similar items (products, cards, list items), proper HTML structure helps users understand: how many items exist, which item they're on, and when they move to the next. Compare the examples below.
Shopping Cart:
What screen readers announce:
"Shopping Cart"
"bullet iPhone 15 Pro $999"
"bullet AirPods Pro $249"
"bullet MagSafe Charger $39"
⚠️ No list context! User doesn't know there are 3 items or their position.
<!-- BAD: Not a semantic list -->
<div>
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div> Shopping Cart:
What screen readers announce:
"Shopping Cart"
"list, Shopping cart items, 3 items"
"1 of 3, iPhone 15 Pro $999"
"2 of 3, AirPods Pro $249"
"3 of 3, MagSafe Charger $39"
✓ Full context! User knows total count and current position.
<!-- GOOD: Semantic list -->
<ul aria-label="Shopping cart">
<li>iPhone - $999</li>
<li>AirPods - $249</li>
<li>Charger - $39</li>
</ul> <ul>/<li> gives full context. Add aria-label to describe what the list contains.
Accessibility tree:
generic ├─ generic │ ├─ img (no alt!) │ ├─ generic "Product A" │ ├─ generic "$49.99" │ └─ generic "Add" ├─ generic │ └─ ...same mess...
⚠️ No structure! Everything is "generic".
<!-- BAD: No semantic structure -->
<div class="card">
<img src="...">
<div>Product A</div>
<div onclick="add()">Add</div>
</div> $49.99
$79.99
Accessibility tree:
list "Product listing" (2 items) ├─ listitem (1 of 2) │ └─ article │ ├─ img "Product A thumbnail" │ ├─ heading "Product A" │ ├─ text "$49.99" │ └─ button "Add to cart" ├─ listitem (2 of 2) │ └─ article │ └─ ...
✓ Clear structure! Each card is an article inside a list.
<!-- GOOD: Semantic card structure -->
<ul role="list" aria-label="Products">
<li>
<article>
<img src="..." alt="Product A">
<h4>Product A</h4>
<button>Add to cart</button>
</article>
</li>
</ul> <ul><li> for list semantics. Use <article> for self-contained content.
Use arrow keys to navigate between tabs:
This is the product description panel. Full details about the product go here.
<div role="tablist">
<button role="tab" aria-selected="true">
Tab 1
</button>
<button role="tab" aria-selected="false">
Tab 2
</button>
</div>
<div role="tabpanel">
Content here
</div> role="tablist", role="tab", role="tabpanel". Use arrow keys to navigate, Tab to enter/exit the group.
role="region" with aria-label to create named sections. Screen readers can jump between regions with shortcuts.