[ui5-dynamic-side-content]: accessibilityAttributes role "none"/"presentation" cannot remove the landmark because aria-label is always applied
Maintainer thường phản hồi trong vòng 3 ngày
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 80/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- html, typescript
- Lĩnh vực
- accessibility, frontend
Hướng nghiên cứu
Bắt đầu trong packages/fiori/src/DynamicSideContent.ts, trong getter accInfo nơi sideContent và vùng chứa chính xây dựng ariaLabel và role; lưu ý các fallback i18n DSC_SIDE_ARIA_LABEL và DSC_MAIN_ARIA_LABEL. Giải quyết role trước, sau đó bỏ ariaLabel (và fallback i18n) khi role đó là none, presentation hoặc undefined, cho cả hai vùng chứa. Hoàn thành nghĩa là <aside> được render không mang aria-label khi role: "none" được đặt và cây trợ năng không còn hiển thị landmark complementary lồng nhau, được xác minh dựa trên các bài kiểm thử DynamicSideContent hiện có.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Bug Description
Follow-up to #13013 / PR #13476.
#13013 requested customizable ARIA roles for ui5-dynamic-side-content so it can be nested inside a page that already has a main landmark. PR #13476 added a role field to accessibilityAttributes and #13013 was closed as resolved.
However, the new role option cannot actually remove the landmark on the side (or main) container, so the original APG violation still occurs. Setting sideContent.role to "none"/"presentation" has no effect on the exposed landmark, because the component unconditionally applies a non-empty aria-label to the same element. Per the WAI-ARIA Presentational Roles Conflict Resolution, a role="none"/"presentation" element that also carries a global ARIA property such as aria-label has its presentational role ignored and its implicit role restored — so <aside> reverts to complementary.
Affected Component
ui5-dynamic-side-content
Expected Behaviour
When the resolved role of the main/side container is "none", "presentation", or undefined, the container should not be exposed as a landmark. Concretely, in that case the component should omit the container's aria-label (and skip the DSC_MAIN_ARIA_LABEL / DSC_SIDE_ARIA_LABEL i18n fallback), so that role="none" actually takes effect.
Isolated Example
No StackBlitz; the issue reproduces with plain markup (the web component renders exactly this into its shadow DOM). Minimal repro:
<main>
<aside role="none" aria-label="Side Content">
<div role="region" aria-label="Filter Panel">Filters</div>
</aside>
</main>
Steps to Reproduce
- Render a
ui5-dynamic-side-contentinside a page that already exposes amainlandmark. - Set
accessibilityAttributes = { sideContent: { role: "none" } }(or{ role: undefined }). - Inspect the computed accessibility tree (Chrome DevTools → Elements → Accessibility, or a screen reader's landmark list).
- Observe the side container is still exposed as a
complementarylandmark nested insidemain.
Log Output, Stack Trace or Screenshots
Rendered side container (shadow DOM):
<aside role="none" aria-label="Side Content" class="ui5-dsc-side">…</aside>
Computed accessibility tree — landmark is still present, nested in main:
main
complementary "Side Content"
region "Filter Panel"
The only state that actually drops the landmark is role="none" with no aria-label:
main
region "Filter Panel" ← complementary gone, child region preserved
role: undefined does not help either: it only removes the role attribute, and a bare <aside> with an accessible name is still an implicit complementary landmark.
Priority
High
Environment Info
UI5 Web Components Version
@ui5/webcomponents-fiori 2.25.x (reproduced; accInfo unchanged on main as of filing)
Browser
Chrome
Operating System
macOS
Additional Info
Additional Context
Root cause — in accInfo (packages/fiori/src/DynamicSideContent.ts):
sideContent: {
ariaLabel: sideContentAttr.ariaLabel || DynamicSideContent.i18nBundle.getText(DSC_SIDE_ARIA_LABEL),
role: hasSideRole ? sideContentAttr.role : "complementary",
},
The role line is correct — passing role: "none" yields role="none" on the <aside>. The problem is the ariaLabel line above it: it is always truthy (falls back to the i18n default), and no prop value can blank it, so the presentational role is always nullified by conflict resolution.
Suggested fix (side shown; same for main):
const sideRole = hasSideRole ? sideContentAttr.role : "complementary";
const sidePresentational = sideRole === "none" || sideRole === "presentation" || sideRole === undefined;
sideContent: {
ariaLabel: sidePresentational
? undefined
: (sideContentAttr.ariaLabel || DynamicSideContent.i18nBundle.getText(DSC_SIDE_ARIA_LABEL)),
role: sideRole,
},
Business impact — the SuccessFactors shell renders role="main" on the page content area, so any embedded DynamicSideContent produces a complementary (and previously a second main) landmark nested inside main — a WAI-ARIA APG violation flagged in accessibility audits. The role property from #13476 is the intended mitigation but cannot take effect while the aria-label is forced.
cc @DMihaylova — follow-up to #13013, since PR #13476 does not fully resolve it.
Organization
SAP-SF
Declaration
- I’m not disclosing any internal or sensitive information.
- Ngôn ngữ chính
- TypeScript
- Star
- 1.8k
- Fork
- 290
- Merge trung bình
- 3 ngày 12 giờ
- Pull request đã merge (30 ngày)
- 54
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của UI5/webcomponents
-
bug Medium Prio TOPIC P
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
UI5/webcomponents#14239 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 3 ngày
-
[Feature Request][Side Navigation][A11Y]: Enhance user experience navigating components tree itemsCó thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mởbug Medium Prio TOPIC RD
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
UI5/webcomponents#14232 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 3 ngày
-
enhancement feature request TOPIC RD
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
UI5/webcomponents#14222 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 3 ngày
-
[SF][A11y][ui5-select] Conflicting ARIA: role="combobox" rendered with aria-roledescription="Listbox" (confuses screen-reader users)Có thể đã có người làm @PetyaMarkovaBogdanova đã nhận 4 ngày trước. Đang mởbug Medium Prio TOPIC P
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 67/100
UI5/webcomponents#14212 · 2 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 3 ngày
-
(ui5-search): Search input missing aria-descriptionCó thể đã có người làm @ndeshev đã nhận 4 ngày trước. Đang mởbug Low Prio TOPIC RL
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
UI5/webcomponents#14211 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 3 ngày
Tất cả issue của UI5/webcomponents
Issue tương tự
-
Add API: BlockVectra Data APIĐang mở
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 74/100
Maintainer thường phản hồi trong vòng 2 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
remotion-dev/remotion#12905 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
supermomonga/paseo-plugin-zcode-provider#83 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
oxidecomputer/skepsis#102 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
voidzero-dev/void#677 ·
Maintainer thường phản hồi trong vòng 1 ngày