Testing aria-setsize and aria-posinset

aria-setsize defines the total number of items in a set. aria-posinset defines the position of the current item within that set. They are almost always used together, and together they let assistive technologies announce something like "Reports, 1 of 3" when a user navigates to an item.

These attributes are most commonly needed when the full set of items is not all present in the DOM at once — for example, in a virtualised list or a treegrid where some rows are collapsed. Without them, a screen reader can only report what it can see, which may be fewer items than actually exist in the logical structure.

The example below is a flat, fully visible treegrid representing a company file structure, going down to four levels of depth. Because all rows are present in the DOM, the attributes are technically optional here — but the example is designed to let you inspect and test them directly, including how the count resets for each sibling group at each level.

Treegrid example: company file structure

This treegrid has three top-level departments, each containing folders and files at varying depths. The deepest items sit at level 4. All rows are visible at once, making it straightforward to inspect the aria-setsize and aria-posinset values with a bookmarklet.

Name Type Modified
Finance Folder 12 Aug 2026
Budget Folder 10 Aug 2026
2025.xlsx Spreadsheet 3 Jan 2025
2026.xlsx Spreadsheet 1 Jan 2026
Reports Folder 5 Aug 2026
Q3.pdf PDF 5 Aug 2026
Engineering Folder 14 Aug 2026
Frontend Folder 14 Aug 2026
src Folder 14 Aug 2026
Button.jsx JSX file 13 Aug 2026
Modal.jsx JSX file 12 Aug 2026
tests Folder 11 Aug 2026
Backend Folder 10 Aug 2026
api.md Markdown 9 Aug 2026
Marketing Folder 8 Aug 2026
Campaigns Folder 7 Aug 2026
Spring2026 Folder 6 Aug 2026
brief.docx Word doc 6 Aug 2026
Assets Folder 4 Aug 2026
logo.svg SVG 3 Aug 2026
brand.pdf PDF 1 Aug 2026

Setsize and posinset map

The diagram below shows how aria-setsize and aria-posinset are scoped to sibling groups, not to the treegrid as a whole. Each group restarts its own count. R1 is the header row counted by aria-rowcount.

R1:  aria-rowcount: 22 (1 header row + 21 data rows)
R2:  Finance              (Level 1, 1 of 3)
R3:    Budget             (Level 2, 1 of 2)
R4:      2025.xlsx        (Level 3, 1 of 2)
R5:      2026.xlsx        (Level 3, 2 of 2)
R6:    Reports            (Level 2, 2 of 2)
R7:      Q3.pdf           (Level 3, 1 of 1)
R8:  Engineering          (Level 1, 2 of 3)
R9:    Frontend           (Level 2, 1 of 2)
R10:     src              (Level 3, 1 of 2)
R11:       Button.jsx     (Level 4, 1 of 2)
R12:       Modal.jsx      (Level 4, 2 of 2)
R13:     tests            (Level 3, 2 of 2)
R14:   Backend            (Level 2, 2 of 2)
R15:     api.md           (Level 3, 1 of 1)
R16: Marketing            (Level 1, 3 of 3)
R17:   Campaigns          (Level 2, 1 of 2)
R18:     Spring2026       (Level 3, 1 of 1)
R19:       brief.docx     (Level 4, 1 of 1)
R20:   Assets             (Level 2, 2 of 2)
R21:     logo.svg         (Level 3, 1 of 2)
R22:     brand.pdf        (Level 3, 2 of 2)

Expected result: navigating through rows, a screen reader should announce each item's position within its sibling group (for example "2 of 2") and its level. The counts reset for each group — the two level-3 items inside Budget are "1 of 2" and "2 of 2", completely independent of the level-3 items inside Frontend or Marketing.

Note for testing: confirm with your standard browser and screen reader combinations that level and position announcements are consistent across different screen reader and browser pairings.