details元素无name属性且不支持原生互斥折叠;需用JS监听toggle事件手动关闭其他项,并确保初始仅一个open以实现手风琴效果。

details 元素本身**没有 name 属性**,也不支持原生互斥折叠。这是个常见误解——浏览器规范里 details 的 HTML 属性只包括 open,不接受 name,加了也无效。
为什么给 details 加 name 没用
HTML 标准中 <details> 是无表单语义的容器元素,不像 <input> 或 <radio> 那样参与表单分组逻辑。name 属性对它完全被忽略,开发者工具里能看到但 JS 读不到、CSS 选不到、行为不受影响。
实现手风琴互斥的最小可行方案(纯 JS)
监听所有 details 的 toggle 事件,在展开一个时手动关闭其他已打开的:
document.querySelectorAll('details.accordion-item').forEach(item => {
item.addEventListener('toggle', () => {
if (item.open) {
document.querySelectorAll('details.accordion-item:not(:is(#' + item.id + '))')
.forEach(other => other.open = false);
}
});
});
- 必须给每个
details加 class(如accordion-item)或统一标识,否则无法批量操作 - 推荐同时加
id,避免用索引或 DOM 位置判断,防止动态插入/删除出错 - 不要用
click代替toggle:用户通过键盘(空格/回车)触发展开时,click不会捕获
兼容性与可访问性注意点
手风琴交互必须保留键盘和屏幕阅读器可用性,原生 details 已自带这些能力,但 JS 控制时容易破坏:
- 别用
display: none或移除 DOM 来“隐藏”内容——这会让屏幕阅读器跳过,且破坏details的语义 - 保持
open属性的同步:JS 修改other.open = false是正确做法,不是操作 class 或样式 - Chrome/Firefox/Safari 均支持
toggle事件,无需 polyfill;旧版 Safari(≤15.4)需监听click+keydown回退
details 都可能被用户手动展开——哪怕你 JS 逻辑写对了,初始页面若多个 open 同时存在,视觉上就不是手风琴。得靠服务端或初始化脚本确保仅一个有 open 属性,这点常被忽略。



















