details默认折叠且无默认展开属性,必须用open属性控制;summary为必填子元素且需含可访问文字;箭头样式须用css伪元素覆盖;应监听toggle事件而非click;嵌套及表单需注意可访问性。

details标签默认不展开,summary文字必须手动写
details 默认处于折叠状态,里面的内容不会显示,这点和手写 CSS + JS 的折叠组件不同——它不依赖 JavaScript,但也没有“默认展开”属性。想一拍就开,得加 open 属性:<details open></details>。而 summary 不是可选的:没有它,details 就不会渲染出可点击的标题行,浏览器会直接忽略整个结构或只显示内部内容(行为不一致,别省略)。
常见错误是把 summary 当成纯装饰,写成空标签或只放图标:<summary></summary>。这样用户点不了,屏幕阅读器也读不到触发点。务必在里面放有意义的文字,哪怕只是“点击查看”。
summary里的图标需要CSS控制,不能靠HTML自带
浏览器对 summary 前面的小箭头(▶/▼)是内置样式,无法用 HTML 属性改,只能用 CSS 覆盖。比如想换成「+」「−」或 SVG 图标,得先用 list-style: none 清掉默认箭头,再用 ::before 伪元素注入内容:
summary {
list-style: none;
}
summary::before {
content: "▶ ";
}
details[open] summary::before {
content: "▼ ";
}
注意两点:一是 summary 必须是 details 的**第一个子元素**,否则伪元素可能不生效;二是某些旧版 Safari 对 details[open] 的选择器支持不稳定,建议加个 class 做兜底(如 details.is-open),用 JS 切换。
JS监听展开收起要用 toggle 事件,不是 click
想在折叠状态变化时执行逻辑(比如统计点击、懒加载内容),不能监听 summary 的 click,因为用户也可能通过键盘(空格/回车)触发,而且 click 在 details 元素上不会冒泡到正确时机。应该监听 details 自身的 toggle 事件:
document.querySelector('details').addEventListener('toggle', (e) => {
if (e.target.open) {
console.log('已展开');
} else {
console.log('已收起');
}
});
这个事件在 DOM 中只在 open 属性值实际改变后触发,且兼容性良好(Chrome 12+、Firefox 49+、Safari 15.4+)。IE 完全不支持 details,如果必须兼容,得用 feature detection 加降级方案,而不是试图 polyfill toggle 事件。
嵌套 details 或放表单控件要小心可访问性
嵌套 details 是合法的,但屏幕阅读器对多层折叠的支持参差不齐;更麻烦的是在 details 内部放 input、select 等表单控件——当 details 收起时,这些控件仍存在于 DOM 中,但不可见、不可聚焦,且部分浏览器(如旧 Edge)会让它们保留在 tab 键顺序里,造成键盘导航“卡住”。
- 如果内容含表单,建议收起时用
display: none或hidden属性彻底移出渲染流(配合 JS 同步open状态) - 避免三层以上嵌套,优先用清晰的层级标题替代
- 不要给
summary加tabindex:它本就是可聚焦元素,加了反而干扰语义
最常被忽略的一点:很多人以为 details 只是个视觉组件,其实它的语义是“用户可选的附加信息”,所以用在隐私政策、技术参数、错误详情这类场景最合适;拿它做主导航或主内容区折叠,既不符合语义,也会让辅助技术用户迷失上下文。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











