aria-expanded必须加在触发展开/收起的按钮上,如,而非被控制的内容容器;需用setattribute动态更新值,并与视觉状态严格同步。

aria-expanded 该加在哪个元素上
它必须加在触发展开/收起的按钮上,比如 <button></button>,而不是加在被控制的内容容器(如 <div>)里。这是最常踩的坑:把 <code>aria-expanded 放到面板上,屏幕阅读器就完全感知不到状态变化了。
- 触发按钮需有 id,否则 aria-controls 关联会失效
- 内容区用 id 匹配,并加上 role="region"(或 role="tabpanel",视语义而定)
- 示例:<button id="toggle-btn" aria-expanded="false" aria-controls="panel-1">详情</button><div id="panel-1" role="region">…</div>怎么动态更新 aria-expanded 的值
不能只靠 CSS 类切换或 display 变更来“模拟”状态;必须用 JavaScript 显式调用 setAttribute 更新属性值。
- 展开时:button.setAttribute('aria-expanded', 'true')
- 收起时:button.setAttribute('aria-expanded', 'false')
- 别写 button.ariaExpanded = true —— 这不是标准 DOM 属性,IE 和旧版 Safari 不支持
- 更新时机必须严格对齐真实可视状态:先改 DOM 可见性(如 hidden 或 height),再设 aria-expanded,顺序反了会导致读屏器播报错误
为什么光靠 aria-expanded 无法驱动图标旋转aria-expanded 是给辅助技术看的状态标记,浏览器不会监听它的变更去触发 CSS 重绘。
- 写了 [aria-expanded="true"] { transform: rotate(90deg); } 没用,因为属性是 JS 动态设置的,CSS 不响应变更
- 正确做法是同步操作:
- button.setAttribute('aria-expanded', 'true')
- button.classList.add('is-expanded')
- 然后用 .is-expanded 类写 CSS 动画或旋转逻辑
- 否则会出现“图标没转但读屏器说已展开”,或“图标转了但读屏器还说已折叠”的可访问性断裂
能不能不用 JavaScript 手动管理 aria-expanded
能,优先用原生 <details></details> + <summary></summary>。它自动处理所有状态:
- 内置键盘支持(空格/回车触发)
- 自动同步 aria-expanded、aria-controls 和焦点管理
- Chrome 12+、Firefox 49+、Safari 6+、Edge 79+ 全支持,IE 除外
- 错误做法:给 <div> 加 <code>onclick 并手动切 display —— 直接丢掉键盘可访问性和读屏器感知
- 如果必须自定义样式或动画,可在 <details></details> 外层包一层容器,用 CSS 覆盖默认行为,但别破坏其内部结构
display 变更来“模拟”状态;必须用 JavaScript 显式调用 setAttribute 更新属性值。
- 展开时:button.setAttribute('aria-expanded', 'true')
- 收起时:button.setAttribute('aria-expanded', 'false')
- 别写 button.ariaExpanded = true —— 这不是标准 DOM 属性,IE 和旧版 Safari 不支持
- 更新时机必须严格对齐真实可视状态:先改 DOM 可见性(如 hidden 或 height),再设 aria-expanded,顺序反了会导致读屏器播报错误
为什么光靠 aria-expanded 无法驱动图标旋转aria-expanded 是给辅助技术看的状态标记,浏览器不会监听它的变更去触发 CSS 重绘。
- 写了 [aria-expanded="true"] { transform: rotate(90deg); } 没用,因为属性是 JS 动态设置的,CSS 不响应变更
- 正确做法是同步操作:
- button.setAttribute('aria-expanded', 'true')
- button.classList.add('is-expanded')
- 然后用 .is-expanded 类写 CSS 动画或旋转逻辑
- 否则会出现“图标没转但读屏器说已展开”,或“图标转了但读屏器还说已折叠”的可访问性断裂
能不能不用 JavaScript 手动管理 aria-expanded
能,优先用原生 <details></details> + <summary></summary>。它自动处理所有状态:
- 内置键盘支持(空格/回车触发)
- 自动同步 aria-expanded、aria-controls 和焦点管理
- Chrome 12+、Firefox 49+、Safari 6+、Edge 79+ 全支持,IE 除外
- 错误做法:给 <div> 加 <code>onclick 并手动切 display —— 直接丢掉键盘可访问性和读屏器感知
- 如果必须自定义样式或动画,可在 <details></details> 外层包一层容器,用 CSS 覆盖默认行为,但别破坏其内部结构
<details></details> + <summary></summary>。它自动处理所有状态:
- 内置键盘支持(空格/回车触发)
- 自动同步 aria-expanded、aria-controls 和焦点管理
- Chrome 12+、Firefox 49+、Safari 6+、Edge 79+ 全支持,IE 除外
- 错误做法:给 <div> 加 <code>onclick 并手动切 display —— 直接丢掉键盘可访问性和读屏器感知
- 如果必须自定义样式或动画,可在 <details></details> 外层包一层容器,用 CSS 覆盖默认行为,但别破坏其内部结构
复杂点在于:状态同步不是“一次设置就完事”,而是每次交互都得检查真实 DOM 可见性、更新属性、同步视觉反馈、保障焦点流——漏掉任意一环,对屏幕阅读器用户就是不可用的。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。










