正确读取和设置 aria-expanded 必须用字符串 "true"/"false":读取用 getattribute('aria-expanded') === 'true',设置用 setattribute('aria-expanded', isopen ? 'true' : 'false') 或 toggleattribute('aria-expanded', isopen);必须绑定在按钮上并配 aria-controls,初始值不可省略。

必须用 JavaScript 显式调用 setAttribute 更新为字符串 "true" 或 "false",不能靠 CSS 类切换、不能赋布尔值、不能只改 display 就完事。
点击事件里怎么安全读取和设置 aria-expanded
常见错误是直接用 !!button.getAttribute('aria-expanded') 判断——"false" 字符串会被转成 true,导致状态翻转错乱。
- 正确读取:
button.getAttribute('aria-expanded') === 'true' - 正确设置:
button.setAttribute('aria-expanded', isOpen ? 'true' : 'false') - 现代写法(推荐):
button.toggleAttribute('aria-expanded', isOpen)——注意第二个参数是布尔值,它会自动增删属性并设值,不是单纯 toggle 存在与否 - 别用
button.ariaExpanded = true:非标准属性,IE 和旧 Safari 不识别
为什么不能等 CSS 动画结束再更新 aria-expanded
屏幕阅读器不等动画,它只看 DOM 属性当前值。如果先启动 height 过渡、再 setAttribute,中间几帧里 aria-expanded="false" 但内容已可见,AT 就会误报“已收起”。
- 更新顺序必须是:先改视觉状态(如
content.classList.toggle('is-open')),立刻同步setAttribute - 不要把
setAttribute放在transitionend回调里 - 如果用
max-height动画,确保初始max-height: 0对应aria-expanded="false",展开后设为具体像素值 +aria-expanded="true"
aria-expanded 必须绑定在按钮上,而不是内容容器
把它写在 <ul></ul> 或 <div class="panel"> 上,屏幕阅读器根本不会把它和按钮操作关联起来——状态语义彻底丢失。
<ul>
<li>正确位置:<code><button aria-expanded="false" aria-controls="panel-1">标题</button>
id="panel-1",且建议加 role="region" 和 aria-labelledby="panel-1"
<div role="button"> 模拟按钮,必须加 <code>tabindex="0" 并监听 Enter/Space 键,否则键盘用户无法触发
最易被忽略的是:初始 HTML 中 aria-expanded 不能省略或留空,必须显式写成 aria-expanded="false" 或 aria-expanded="true";否则某些 AT 会跳过该控件,或者默认当成未定义状态处理。











