Loading Developer Playground

Loading ...

Skip to main content
ARIA ATTRIBUTERelationship Attributes

aria-setsize

Defines the number of items in the current set of listitems or treeitems when not all items are present in the DOM.

Value Type
Integer
Special Value
-1 = unknown size
Paired With
aria-posinset

Overview

The aria-setsize attribute defines the total number of items in the current set. It works together with aria-posinset to help assistive technologies convey position information.

When the total size is unknown (infinite scroll, lazy loading), use aria-setsize="-1" to indicate the size cannot be determined.

Each nested level in a tree structure has its own setsize, referring to the number of siblings at that level.

Live Demo: Dynamic Set Size

Adjust set size to see how it affects item announcements:
25
  • Item 11 of 25

    aria-setsize="25" aria-posinset="1"

  • Item 22 of 25

    aria-setsize="25" aria-posinset="2"

  • Item 33 of 25

    aria-setsize="25" aria-posinset="3"

  • Item 44 of 25

    aria-setsize="25" aria-posinset="4"

  • Item 55 of 25

    aria-setsize="25" aria-posinset="5"

(Showing first 5 items of 25)

aria-setsize tells screen readers the total number of items. When you change the value, screen readers will announce "item X of 25" accordingly.

Code Examples

Basic Usage

<!-- aria-setsize defines total items in a set -->

<!-- Showing 3 of 50 results -->
<ul role="listbox" aria-label="Search results">
  <li role="option" aria-posinset="1" aria-setsize="50">
    Result 1 of 50
  </li>
  <li role="option" aria-posinset="2" aria-setsize="50">
    Result 2 of 50
  </li>
  <li role="option" aria-posinset="3" aria-setsize="50">
    Result 3 of 50
  </li>
</ul>

<!-- Screen reader announces "item 1 of 50" for first item -->

Unknown Size

<!-- When total size is unknown, use aria-setsize="-1" -->

<!-- Infinite scroll / lazy loading -->
<ul role="listbox" aria-label="Feed items">
  <li role="option" 
      aria-posinset="1" 
      aria-setsize="-1">
    Post 1
  </li>
  <li role="option" 
      aria-posinset="2" 
      aria-setsize="-1">
    Post 2
  </li>
  <li role="option" 
      aria-posinset="3" 
      aria-setsize="-1">
    Post 3
  </li>
  <!-- More items load as user scrolls -->
</ul>

<!-- -1 indicates "size unknown" to assistive technology -->

Dynamic Content

<!-- Dynamically updated set size -->

<div role="listbox" aria-label="Shopping cart items">
  <!-- Items can be added/removed dynamically -->
  <div role="option" 
       aria-posinset="1" 
       aria-setsize="3">
    Product A - $29.99
    <button aria-label="Remove Product A">Remove</button>
  </div>
  
  <div role="option" 
       aria-posinset="2" 
       aria-setsize="3">
    Product B - $49.99
    <button aria-label="Remove Product B">Remove</button>
  </div>
  
  <div role="option" 
       aria-posinset="3" 
       aria-setsize="3">
    Product C - $19.99
    <button aria-label="Remove Product C">Remove</button>
  </div>
</div>

<!-- When item removed, update all aria-posinset 
     and aria-setsize values -->

Tree Structure

<!-- aria-setsize in tree structure -->

<ul role="tree" aria-label="Project files">
  <!-- Root level has 3 items -->
  <li role="treeitem" 
      aria-posinset="1" 
      aria-setsize="3"
      aria-expanded="true">
    src/
    <ul role="group">
      <!-- Nested level has 4 items -->
      <li role="treeitem" 
          aria-posinset="1" 
          aria-setsize="4">
        index.ts
      </li>
      <li role="treeitem" 
          aria-posinset="2" 
          aria-setsize="4">
        utils.ts
      </li>
      <li role="treeitem" 
          aria-posinset="3" 
          aria-setsize="4">
        types.ts
      </li>
      <li role="treeitem" 
          aria-posinset="4" 
          aria-setsize="4">
        components/
      </li>
    </ul>
  </li>
  
  <li role="treeitem" 
      aria-posinset="2" 
      aria-setsize="3">
    package.json
  </li>
  
  <li role="treeitem" 
      aria-posinset="3" 
      aria-setsize="3">
    README.md
  </li>
</ul>

<!-- Each level has its own setsize -->

React Components

// React components with aria-setsize
import { useState, useMemo } from 'react';

// Dynamic list with automatic setsize
function DynamicList({ items, label }) {
  return (
    <ul role="listbox" aria-label={label}>
      {items.map((item, index) => (
        <li
          key={item.id}
          role="option"
          aria-posinset={index + 1}
          aria-setsize={items.length}
        >
          {item.content}
        </li>
      ))}
    </ul>
  );
}

// Paginated/filtered list with true total
function FilteredList({ 
  visibleItems, 
  totalCount, 
  startIndex,
  label 
}) {
  // totalCount might be -1 if unknown
  const setSize = totalCount === -1 ? -1 : totalCount;

  return (
    <ul role="listbox" aria-label={label}>
      {visibleItems.map((item, index) => (
        <li
          key={item.id}
          role="option"
          aria-posinset={startIndex + index + 1}
          aria-setsize={setSize}
        >
          {item.content}
        </li>
      ))}
    </ul>
  );
}

// Tree with automatic position tracking
function TreeNode({ item, position, siblingCount, children }) {
  const [expanded, setExpanded] = useState(false);
  const childCount = children?.length || 0;

  return (
    <li
      role="treeitem"
      aria-posinset={position}
      aria-setsize={siblingCount}
      aria-expanded={childCount > 0 ? expanded : undefined}
    >
      <button onClick={() => setExpanded(!expanded)}>
        {item.name}
      </button>
      
      {expanded && childCount > 0 && (
        <ul role="group">
          {children.map((child, idx) => (
            <TreeNode
              key={child.id}
              item={child}
              position={idx + 1}
              siblingCount={childCount}
              children={child.children}
            />
          ))}
        </ul>
      )}
    </li>
  );
}

// Shopping cart with dynamic updates
function ShoppingCart({ items, onRemove }) {
  return (
    <div role="listbox" aria-label="Cart items">
      {items.map((item, index) => (
        <div
          key={item.id}
          role="option"
          aria-posinset={index + 1}
          aria-setsize={items.length}
        >
          <span>{item.name} - ${item.price}</span>
          <button
            onClick={() => onRemove(item.id)}
            aria-label={`Remove ${item.name} from cart`}
          >
            Remove
          </button>
        </div>
      ))}
    </div>
  );
}

Related Attributes

Specifications & Resources