Feed

Description

A feed is a dynamic, scrollable list of articles where new content can be added or removed as the user scrolls. A feed is a specialized form of a list in which articles are presented in a chronological or relevance-based order. Feed content loads dynamically—typically as the user scrolls—so the complete set of articles may not be present in the DOM at any given time.

Feeds are commonly used for social media timelines, news aggregators, blog indexes, and any interface where an unbounded stream of content is presented as a series of discrete items.

A feed uses role="feed" on the container element, and each item within the feed must be an element with role="article". The feed role signals to assistive technologies that the content is a dynamically updating stream, enabling specialized navigation and reading behaviors.

When to use

  • Use a feed when presenting a dynamically loading, scrollable list of articles or content items where new entries may appear as the user scrolls.

  • Use a feed when the total number of items is unknown or changes over time, and items are loaded incrementally.

  • Do not use a feed for static lists of content. Use a standard list or series of <article> elements instead.

  • Do not use a feed as a substitute for a listbox or menu. Those patterns carry different semantics and keyboard interaction models.

Feed structure

A feed widget is built using ARIA roles to communicate structure and semantics to assistive technologies.

Feed roles

The following ARIA roles define a feed widget and its items:

RolePurpose
feedIdentifies a container as a feed — a dynamic, scrollable list of articles.
articleIdentifies an element as an article within the feed. Each discrete content item in the feed must have this role.

Each article element must be a direct or owned child of the feed container.

Feed ARIA attributes

ARIA attributes must be set to convey the feed's state and properties to assistive technologies.

  • Accessible name: The feed element must have an accessible name, typically provided via aria-label or aria-labelledby. This is especially important when a page contains multiple feeds.

  • Article labels: Each article element within the feed should have an accessible name that clearly describes its content or purpose. This is commonly provided by a heading element within the article, referenced via aria-labelledby, or by an aria-label attribute.

  • Busy state: When the feed is loading new content, set aria-busy="true" on the feed element. Once the update is complete, set aria-busy back to "false". This prevents assistive technologies from announcing incomplete or changing content during the update.

  • Set size and position: Each article element should have aria-setsize set to the total number of articles loaded (or -1 if the total is unknown) and aria-posinset set to its ordinal position within the feed. These attributes help screen reader users understand where they are in the feed and how many items are available.

Feed code example
1<div role="feed" aria-label="Latest news">
2 <article
3 aria-labelledby="article-1-title"
4 aria-posinset="1"
5 aria-setsize="50"
6 tabindex="0"
7 >
8 <h2 id="article-1-title">First article heading</h2>
9 <p>Article content...</p>
10 </article>
11 <article
12 aria-labelledby="article-2-title"
13 aria-posinset="2"
14 aria-setsize="50"
15 tabindex="0"
16 >
17 <h2 id="article-2-title">Second article heading</h2>
18 <p>Article content...</p>
19 </article>
20</div>

Structure and semantics

All users must be able to identify a feed, understand its structure, and distinguish between its articles. Semantic roles and attributes communicate the feed's purpose, the nature of its items, and any state information to assistive technologies.

Semantic and structure accessibility tests

Element has incorrect role
StandardCriteria
WCAG4.1.2 Name, Role, Value
EN 301 5499.4.1.2 Name, Role, Value
Section 5081194.21(d)

Impact: Critical

Feed components must use the correct ARIA role to be identified as feeds by assistive technologies. The container element must have role="feed". Using an incorrect role — such as role="list" or no role — causes assistive technologies to misrepresent the widget's purpose and interaction model to users.

Ensure that:

  • The container element has role="feed".
  • Each content item within the feed has role="article".
Incorrect root element
StandardCriteria
WCAGN/A
EN 301 549N/A
Section 508N/A

Impact: Needs review

The Evinced Unit Tester might report this violation in case it identified a child element with a role of feed nested inside the provided locator. Verify that the locator passed to the test is the outermost element of the feed widget, and that role="feed" is set on the correct container element.

Missing contextual labeling
StandardCriteria
WCAG1.3.1 Info and Relationships
EN 301 5499.1.3.1 Info and Relationships
Section 508N/A

Impact: Moderate

A feed without an accessible name provides no context to screen reader users about the purpose of the widget. This is especially important when a page contains multiple feeds.

Provide an accessible name for every feed:

  • Use aria-labelledby to reference the id of a visible heading or label.
  • Use aria-label when no visible label is available.
1<!-- Labeled by a visible heading -->
2<h2 id="news-heading">Latest news</h2>
3<div role="feed" aria-labelledby="news-heading">
4 ...
5</div>
6
7<!-- Labeled directly -->
8<div role="feed" aria-label="Social media timeline">
9 ...
10</div>
Group members missing accessible names
StandardCriteria
WCAG4.1.2 Name, Role, Value
EN 301 5499.4.1.2 Name, Role, Value
Section 5081194.21(d)

Impact: Critical

Every article element within a feed must have an accessible name. Without one, screen reader users cannot identify or understand the purpose of individual articles, making the feed difficult to navigate.

The accessible name for an article is most commonly derived from a heading element within the article. Use aria-labelledby to reference that heading, or use aria-label when no suitable visible label exists.

1<article aria-labelledby="post-title-1">
2 <h3 id="post-title-1">Article heading here</h3>
3 <p>Article content...</p>
4</article>
Article element not labelled by content
StandardCriteria
WCAG4.1.2 Name, Role, Value
EN 301 5499.4.1.2 Name, Role, Value
Section 5081194.21(d)

Impact: Minor

Each <article> element in a feed should have a label that clearly describes its content or purpose. Without a descriptive label, screen reader users might not understand what the article is about without having to read the entire content.

Make sure each <article> element has a proper label. Use one of these approaches:

  1. Use a heading like <h2> or <h3>.
    • Make sure the heading tags follow a logical order and reflect the content hierarchy.
    • The heading should be placed at the beginning of the article content.
  2. Add aria-labelledby or aria-label attributes.
    • Use aria-labelledby when there is an existing visible element inside the article that can serve as the label.
    • Use aria-label when there is no suitable visible element within the article to serve as the label.
Group contains duplicate names
StandardCriteria
WCAGN/A
EN 301 549N/A
Section 508N/A

Impact: Best practice

Articles within the same feed should have unique accessible names. When two or more articles share the same name, users cannot distinguish between them, which creates a confusing experience for screen reader users navigating by article name.

If duplicate article labels are intentional, provide additional context using aria-describedby or by incorporating distinguishing information into each article's accessible name.

No group members with required role
StandardCriteria
WCAG1.3.1 Info and Relationships
EN 301 5499.1.3.1 Info and Relationships
Section 508N/A

Impact: Serious

A feed container must own at least one element with role="article". If the container has no children with the article role, assistive technologies cannot identify it as a functional feed and users cannot navigate its content.

Ensure the feed container directly owns at least one element with role="article".

Feed content outside article
StandardCriteria
WCAG1.3.1 Info and Relationships
EN 301 5499.1.3.1 Info and Relationships
Section 508N/A

Impact: Minor

The content in feed components must be wrapped in elements with the role="article" attribute. When feed content exists outside of article elements, screen reader users may find it hard to understand and navigate the feed content.

Make sure all feed content is contained inside elements with the role="article" attribute. This helps assistive technology users understand where each piece of content starts and ends in the feed.

Component does not support disabled state
StandardCriteria
WCAG4.1.2 Name, Role, Value
EN 301 5499.4.1.2 Name, Role, Value
Section 5081194.21(d)

Impact: Serious

The disabled or aria-disabled attribute is used on a component that does not support being disabled. Assistive technology users may get incorrect information about the component's state.

Check if the component's role supports the disabled or aria-disabled attribute. If the current role does not support it, consider removing the attribute or using an alternative approach.

Relationships

A feed exists in relationship with its articles and, optionally, with the mechanism that triggers loading of additional content. Structural groupings and ownership relationships within the feed must be programmatically conveyed.

Relationship accessibility tests

Invalid aria-owns values
StandardCriteria
WCAGN/A
EN 301 549N/A
Section 508N/A

Impact: Needs review

Elements referenced by the aria-owns attribute on a feed container have roles that do not conform to the expected child roles for that element. A feed should only own elements with role="article". When the owned elements' roles are incorrect, screen readers may misinterpret the relationships within the feed, which can confuse users.

Avoid using aria-owns if possible. If you must use it:

  • Preserve DOM order: DOM children of the container should come first, followed by elements referenced in aria-owns, unless you explicitly list the DOM children in aria-owns in the desired reading order.
  • Match expected roles: All elements specified in aria-owns must have role="article".
  • Avoid circular references: An element's id must not appear in more than one element's aria-owns attribute at any time.
Avoid aria-owns
StandardCriteria
WCAGN/A
EN 301 549N/A
Section 508N/A

Impact: Needs review

While aria-owns can define a parent-child relationship between elements that are not nested in the DOM, it is often poorly supported by assistive technologies and can produce an unpredictable reading order. For feeds, it is best practice to use standard DOM nesting: place article elements as direct descendants of the feed container.

Operation

Busy state

Feed missing aria-busy attribute
StandardCriteria
WCAG4.1.3 Status Messages
EN 301 5499.4.1.3 Status Messages
Section 508N/A

Impact: Serious

Feeds must use the aria-busy attribute to indicate when they are being updated. When a feed is loading new content, aria-busy="true" must be set on the feed element. After the update is complete, aria-busy must be set back to "false".

Without this attribute, assistive technology users may not be aware that the feed is currently updating. This may cause confusion or the content state may be reported incorrectly.

1<!-- While loading -->
2<div role="feed" aria-label="News feed" aria-busy="true">
3 ...
4</div>
5
6<!-- After loading completes -->
7<div role="feed" aria-label="News feed" aria-busy="false">
8 ...
9</div>

Set size and position

Aria-setsize invalid implementation
StandardCriteria
WCAGN/A
EN 301 549N/A
Section 508N/A

Impact: Best practice

The aria-setsize attribute should be applied to individual items in a set, not to the container element.

It is recommended to follow these steps:

  1. Remove the aria-setsize attribute from the container element.
  2. Add the aria-setsize attribute to each item in the set. The value of aria-setsize should be the total number of items in the set.

Please note: The aria-setsize and aria-posinset attributes should be used only when a portion of the set is present in the document structure at a given moment.

Aria-setsize conflicting values
StandardCriteria
WCAG1.3.1 Info and Relationships
EN 301 5499.1.3.1 Info and Relationships
Section 508N/A

Impact: Moderate

Each item in a set must have the same aria-setsize value. When the aria-setsize attribute values for items in a set do not match, screen reader users may get incorrect information about how many items are in the set.

Make sure all items within the set have the same aria-setsize value. The value of aria-setsize should be the total number of items in the set.

Please note: The aria-setsize and aria-posinset attributes should be used only when a portion of the set is present in the document structure at a given moment.

Aria-posinset invalid implementation
StandardCriteria
WCAGN/A
EN 301 549N/A
Section 508N/A

Impact: Best practice

The aria-posinset attribute should be applied to individual items in a set, not to the container element.

It is recommended to follow these steps:

  1. Remove the aria-posinset attribute from the container element.
  2. Add the aria-posinset attribute to each individual item within the set. The value of aria-posinset should indicate the position of the element within the set of items.
Aria-posinset is larger than aria-setsize
StandardCriteria
WCAG1.3.1 Info and Relationships
EN 301 5499.1.3.1 Info and Relationships
Section 508N/A

Impact: Moderate

The aria-posinset attribute values for articles must not exceed aria-setsize. When an article has an aria-posinset value that is greater than the aria-setsize value, screen reader users may receive confusing or incorrect information about the position of items within the feed.

Make sure the aria-posinset value for each article is a positive integer that is not greater than the aria-setsize value. Check that all items in the set have the correct aria-posinset and aria-setsize values.

Operability tests

Deprecated keypress listener
StandardCriteria
WCAGN/A
EN 301 549N/A
Section 508N/A

Impact: Needs review

The keypress event is deprecated and its behavior is inconsistent across browsers, particularly with non-Latin input methods (IME). For feed keyboard handling, use keydown events instead. The keydown event fires for all keys and is consistently supported across browsers and assistive technology combinations.

keydown event handler example
1feedContainer.addEventListener("keydown", (event) => {
2 switch (event.key) {
3 case "PageDown":
4 focusNextArticle();
5 event.preventDefault();
6 break;
7 case "PageUp":
8 focusPreviousArticle();
9 event.preventDefault();
10 break;
11 }
12});