aria-posinset
Position of an item within a set when the DOM cannot express it — typically because items are virtualized, paginated, or filtered. Always pair with aria-setsize so screen readers can announce "3 of 47".
When to use
When the DOM does not contain the full set — virtualized lists that only render visible items, paginated grids, filtered comboboxes, infinite-scroll feeds. Without aria-posinset and aria-setsize, the screen reader has to guess from sibling count and will announce “item 1 of 10” when really the user is on item 327 of 5,000.
Valid on items inside containers that are inherently set-like: option inside listbox, menuitem inside menu, treeitem inside tree, tab inside tablist, article inside feed, row inside grid.
If the DOM does naturally include every item in source order, you do not need aria-posinset; the AT counts siblings for free.
How it behaves
The value is a positive integer — the 1-based index of this item in the complete set. Pair it with aria-setsize on the same item; both attributes belong on the items themselves, not on the container.
When items are filtered, update both attributes to reflect the visible-and-relevant set, not the original full list. Otherwise users hear positions that don’t match what they can navigate to.
aria-setsize="-1" is valid for cases where the total is genuinely unknown (an open-ended search-as-you-type feed). Some AT announce that as “many”; others stay silent.
Common failures
- Setting
aria-posinsetwithoutaria-setsize. Half the information is missing; AT cannot say “3 of how many”. - Forgetting to update the values after a sort or filter. Users hear stale positions.
- Putting the attributes on the container instead of the items.
- Using
aria-posinsetwhen the DOM already reflects the full set — the AT was going to count correctly anyway, and now you have two sources of truth that can drift. - Zero or negative values for
aria-posinset(negatives are not allowed; onlyaria-setsizeaccepts-1). - Position numbers that don’t match the visual order — a screen-reader user reads “item 5” while the third visible item is highlighted.
Example
<!-- Virtualized listbox: only items 12-16 are in the DOM, but the set is 5,000 long -->
<div role="listbox" aria-label="Customers">
<div role="option" aria-posinset="12" aria-setsize="5000">Customer 12</div>
<div role="option" aria-posinset="13" aria-setsize="5000">Customer 13</div>
<div role="option" aria-posinset="14" aria-setsize="5000" aria-selected="true">Customer 14</div>
<div role="option" aria-posinset="15" aria-setsize="5000">Customer 15</div>
<div role="option" aria-posinset="16" aria-setsize="5000">Customer 16</div>
</div>