[ui5-dynamic-side-content]: accessibilityAttributes role "none"/"presentation" cannot remove the landmark because aria-label is always applied
维护者通常 3 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 2/5
- 预计耗时
- 1-3 小时
- 新手友好度
- 80/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- html, typescript
调研方向
从 packages/fiori/src/DynamicSideContent.ts 开始,在 accInfo getter 中,sideContent 和主容器会构建 ariaLabel 和 role;注意 i18n 回退项 DSC_SIDE_ARIA_LABEL 和 DSC_MAIN_ARIA_LABEL。先解析 role,然后当该 role 为 none、presentation 或 undefined 时,对两个容器都移除 ariaLabel(以及 i18n 回退项)。完成意味着渲染出的 <aside> 不携带 aria-label(当设置了 role: "none" 时),并且无障碍树不再显示嵌套的 complementary landmark,需使用现有的 DynamicSideContent 测试进行验证。
由索引模型根据 Issue 内容生成。
描述
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.
- 主要语言
- TypeScript
- 星标
- 1.8k
- 派生
- 290
- 平均合并
- 3 天 12 小时
- 30 天内合并 PR
- 54
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
UI5/webcomponents 的其他 Issue
-
bug Medium Prio TOPIC P
难度 2/5 1-3 小时 新手友好度 72/100
UI5/webcomponents#14239 · 2 条评论 ·
维护者通常 3 天内回复
-
[Feature Request][Side Navigation][A11Y]: Enhance user experience navigating components tree items未关闭bug Medium Prio TOPIC RD
难度 2/5 1-3 小时 新手友好度 72/100
UI5/webcomponents#14232 · 1 条评论 ·
维护者通常 3 天内回复
-
enhancement feature request TOPIC RD
难度 2/5 1-3 小时 新手友好度 68/100
UI5/webcomponents#14222 · 1 条评论 ·
维护者通常 3 天内回复
-
[SF][A11y][ui5-select] Conflicting ARIA: role="combobox" rendered with aria-roledescription="Listbox" (confuses screen-reader users)可能已有人在做 @PetyaMarkovaBogdanova 于 1 天前认领。 未关闭bug Medium Prio TOPIC P
难度 2/5 1-3 小时 新手友好度 67/100
UI5/webcomponents#14212 · 2 条评论 · 已指派 1 人 ·
维护者通常 3 天内回复
-
(ui5-search): Search input missing aria-description可能已有人在做 @ndeshev 于 1 天前认领。 未关闭bug Low Prio TOPIC RL
难度 2/5 1-3 小时 新手友好度 78/100
UI5/webcomponents#14211 · 已指派 1 人 ·
维护者通常 3 天内回复
查看 UI5/webcomponents 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 85/100
Automattic/data-liberation-agent#1115 ·
维护者通常 1 天内回复
-
bug
难度 2/5 1-3 小时 新手友好度 88/100
维护者通常 1 天内回复
-
CSS enhancement good first issue
难度 2/5 1-3 小时 新手友好度 70/100
pychess/pychess-variants#2448 ·
维护者通常 1 天内回复
-
[architect] Stale planning/scratch files at repo root (COMPONENT_SPLIT_SUMMARY.md etc.) describe already-completed work可能已有人在做 @hivecommons-hive 今天认领。 未关闭agent/architect architecture help wanted stage/040-covered-by-pr tech-debt
难度 2/5 1-3 小时 新手友好度 85/100
kubestellar/console#24716 ·
维护者通常 1 天内回复
-
helm-knative-apply.sh fails with Helm 4可能已有人在做 关联的 PR 仍在进行中或已合并。 未关闭area: triage theme: undefined
难度 2/5 1-3 小时 新手友好度 85/100
jhipster/generator-jhipster#35895 ·
维护者通常 1 天内回复