Skip to content

fix(sidebar): neutral sidebar markup with opt-in landmark roles - #1359

Open
gadenbuie wants to merge 6 commits into
mainfrom
fix/1358-sidebar-role
Open

gadenbuie wants to merge 6 commits into
mainfrom
fix/1358-sidebar-role

Conversation

@gadenbuie

Copy link
Copy Markdown
Member

Fixes #1358

Summary

Sidebars previously used <aside> markup, so every sidebar became a complementary landmark. Screen reader users heard each dashboard sidebar announced as separate complementary content, even when the sidebar held the controls that drive the page's main output.

This PR changes the default sidebar markup to a neutral <div>. The new role argument of sidebar() adds a landmark when the sidebar's content warrants one. sidebar() accepts "form", "search", "complementary", or "region". "complementary" renders an <aside>; the other roles render a <div> with a role attribute.

Landmark roles need an accessible name. sidebar() labels the landmark from its title when one exists, and otherwise requires aria-label or aria-labelledby. An unnamed landmark role is a rendering error.

page_sidebar() now wraps its sidebar and main content in a single <main> element, so a sidebar with role = "form" sits inside the page's main landmark. That layout matches the guidance in the issue: dashboard filters are part of the main content, not complementary to it.

gadenbuie and others added 6 commits September 21, 2026 11:46
Sidebars now render as a plain div by default instead of an aside,
since a sidebar's visual placement doesn't imply its content is
complementary to the main content. The new role argument of sidebar()
opts into a landmark: "complementary" renders a native aside, while
"form", "search", and "region" render a div with the matching ARIA
role. Landmark roles require an accessible name, provided by the
sidebar title (which is wired up via aria-labelledby) or by an
explicit aria-label/aria-labelledby, which always takes precedence.

Part of #1358
page_sidebar() now wraps the entire layout_sidebar() in its single
<main> element, so sidebar controls and content together form the
page's main landmark, instead of only the content area. The page
main container helper gains a gap argument shared with the navbar
variant, and the page-sidebar min-height/min-width rules are
retargeted for the extra <main> wrapper while remaining conditioned
on fillable layouts.

Part of #1358
@gadenbuie
gadenbuie marked this pull request as ready for review September 21, 2026 15:57
@gadenbuie
gadenbuie requested a review from cpsievert September 21, 2026 16:11
Comment thread R/sidebar.R
Comment on lines +212 to 214
if (is.null(x$open)) {
x$open <- sidebar_open_on()
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, this might close at least one other open issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sidebar marked up as aside

2 participants