Skip to content

Tab / TabContainer: Tab expand button (overflow arrow) incorrectly exposed as interactive element to screen readers #8900

Description

@IvyYang01

Description

In the TabContainer component (used internally by ObjectPage), when a Tab has sub-items and its own content (the "two-click area" pattern), the expand/overflow arrow button is rendered as a fully interactive <ui5-button> element. This causes screen readers (e.g., JAWS in VPC mode) to announce it as a separate "More" menu button and expose it in the Button List.

In the SAPUI5 reference implementation (sap.uxap.ObjectPageLayout), the equivalent overflow arrow icon is treated as decorative — it uses role="presentation" and aria-hidden="true", so only the tab itself is exposed to screen readers.

Affected Component

@ui5/webcomponents — Tab / TabContainer (version 2.24.0)

Reproduction Steps

  1. Create an ObjectPage with an ObjectPageSection that contains multiple ObjectPageSubSection children:
<ObjectPage>
  <ObjectPageSection titleText="General Information">
    <ObjectPageSubSection titleText="Details">...</ObjectPageSubSection>
    <ObjectPageSubSection titleText="Description">...</ObjectPageSubSection>
  </ObjectPageSection>
  <ObjectPageSection titleText="Additional Settings">...</ObjectPageSection>
</ObjectPage>
  1. Open the page with JAWS screen reader enabled
  2. Open the JAWS Button List (INSERT + F7) or navigate in Virtual PC Cursor mode
  3. Observe that a "More" button appears as a separate actionable element next to the "General Information" tab

Expected Behavior (SAPUI5 Reference)

The expand/overflow arrow should be decorative only, matching the SAPUI5 sap.uxap.ObjectPageLayout behavior:

<!-- SAPUI5 reference: expand icon is decorative -->
<span role="presentation" aria-hidden="true" aria-label="More"
      class="sapMITBFilterExpandIcon">
</span>
  • role="presentation" — not exposed to accessibility tree
  • aria-hidden="true" — invisible to screen readers
  • No separate focus stop or interactive element
  • The tab itself has aria-haspopup="menu" to indicate it opens a submenu

Reference sample: https://ui5.sap.com/#/entity/sap.uxap.ObjectPageSection/sample/sap.uxap.sample.ObjectPageSection

Actual Behavior (UI5 Web Components)

The expand button is rendered as an interactive <ui5-button> in TabInStripTemplate.js:

// When requiresExpandButton === true (two-click area)
<div class="ui5-tab-expand-button">
  <Button
    icon={slimArrowDownIcon}
    design="Transparent"
    tabindex={-1}
    tooltip={this.expandButtonTitle}  // "More"
    accessibilityAttributes={{ hasPopup: "menu" }}
  />
</div>

This causes:

  • JAWS announces: "More button menu Press down arrow key to open subitems menu"
  • The button appears in the JAWS Button List as a separate actionable item
  • Users may be confused about the relationship between the tab and the "More" button

Root Cause

In Tab.js, the requiresExpandButton getter returns true when a tab has sub-items AND its own content:

get requiresExpandButton() {
    return this.items.length > 0 && this._isTopLevelTab && this.hasOwnContent;
}

This triggers the rendering of a full <Button> component instead of a decorative icon.

Suggested Fix

The expand button in the "two-click area" pattern should follow the SAPUI5 reference approach:

  1. Replace the interactive <Button> with a non-interactive icon element
  2. Add role="presentation" and aria-hidden="true" to the expand icon
  3. Keep aria-haspopup="menu" on the parent tab element (already present)
  4. The click handler can remain on the icon's container <div> without requiring it to be an accessible button

Environment

  • @ui5/webcomponents: 2.24.0
  • @ui5/webcomponents-react: 2.24.1
  • Screen reader: JAWS (latest)
  • Browser: Chrome (latest)

Impact

  • Accessibility: Violates WCAG expectations — decorative elements should not be exposed to assistive technology
  • Usability: Confuses screen reader users who encounter an unexpected "More" button separate from the tab

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions