aria-expanded 和 aria-controls 在折叠面板中的配合写法

aria-expanded 和 aria-controls 必须成对使用并确保 ID 关联与状态同步:aria-controls 指向面板唯一 ID,aria-expanded 动态反映按钮展开状态(true/false),且需与面板显隐一致;面板建议添加 role="region"、aria-labelledb

y 和同步切换的 aria-hidden。

在折叠面板(Accordion)中,aria-expandedaria-controls 需要成对使用,才能让屏幕阅读器正确识别“哪个按钮控制哪块内容”以及“当前是展开还是收起状态”。关键不是单独写对属性,而是确保它们之间存在明确的 ID 关联和状态同步。

aria-controls 指向目标区域的 id

折叠按钮(如 )必须通过 aria-controls 属性,引用其控制的面板容器的唯一 id。这个 id 必须真实存在于 DOM 中,且不能重复。

  • ✅ 正确示例:

    面板内容
  • ❌ 常见错误:
    aria-controls 值拼错、ID 不存在、多个按钮指向同一个 ID 却没做状态隔离

aria-expanded 实时反映按钮当前状态

aria-expanded 是布尔属性,必须根据面板实际可见状态动态更新:展开时为 "true",收起时为 "false"。它只写在触发按钮上,不写在面板上。

  • 初始状态需与面板默认显示一致(例如面板默认隐藏,则按钮初始 aria-expanded="false"
  • JavaScript 切换面板时,必须同步设置:
    button.setAttribute('aria-expanded', 'true');
    button.setAttribute('aria-expanded', 'false');
  • 不要写成 aria-expanded=""aria-expanded="undefined" —— 这会被视为无效值,屏幕阅读器可能忽略

面板容器需配合 role 和 aria-hidden(可选但推荐)

被控制的面板区域建议添加 role="region" 并设置 aria-labelledby 指回按钮的 id,增强语义关联。同时,当面板收起时,加上 aria-hidden="true" 可进一步提示内容不可访问(注意:仅当内容完全隐藏且无需键盘聚焦时使用)。

  • 示例结构:

    内容
  • aria-hidden="true" 要随 aria-expanded 同步切换;若面板用 display: none 隐藏,aria-hidden 可省略(CSS 隐藏已具备可访问性效果),但显式声明更稳妥

避免常见组合陷阱

  • 不要只设 aria-expanded 而不设 aria-controls —— 屏幕阅读器无法知道它控制什么
  • 不要让多个按钮共用同一个 aria-controls 值却各自维护独立状态 —— 应确保每个按钮有唯一配对的面板 ID
  • 不要用 class 名或 data 属性代替 ID 关联 —— aria-controls 只认真实存在的 ID 引用
  • 避免在非交互元素(如 )上加这些属性 —— 它们应只出现在可聚焦、可操作的控件上