details 和 summary 原生实现可折叠列表,summary 必须是 details 的第一个且唯一子元素,支持现代浏览器,可通过 details[open] 和 summary::marker 自定义样式,监听 toggle 事件控制状态。

用 details 和 summary 最快实现可折叠列表
不用写一行 JavaScript,原生 HTML 就能实现点击展开/收起的列表效果。details 是语义化容器,summary 是默认显示的标题行,浏览器自动处理切换逻辑和 ARIA 属性。
常见错误是把 summary 写成多个或放在 details 外面——它必须是 details 的第一个子元素,且只能有一个:
vite
- 支持所有现代浏览器(Chrome 12+、Firefox 49+、Safari 6+),Edge 全版本
- 默认展开需加
open属性: - 不能嵌套
details(部分浏览器会忽略内层)
想自定义箭头或样式?绕不开 summary::marker
浏览器默认在 summary 前加一个三角形标记,但这个标记无法用常规 CSS 选中。真正可控的是 summary::marker 伪元素(Chrome 115+、Firefox 117+、Safari 17.4+ 支持)。
旧版浏览器或需降级处理:用 summary::before + details[open] summary::before 模拟开关状态,但要注意 summary 默认是 display: list-item,容易和伪元素冲突:
summary {
list-style: none;
}
summary::before {
content: "▶";
margin-right: 4px;
}
details[open] summary::before {
content: "▼";
}
-
::marker只能改内容、颜色、字体,不能设宽高或背景 - 若用 JS 动态控制
open属性,CSS 选择器details[open]依然有效 - 避免给
summary设display: block,否则可能丢失默认聚焦行为和键盘支持
需要 JS 控制?监听 toggle 事件比 click 更可靠
details 元素触发的 toggle 事件,专为展开/收起状态变化设计,比监听 click 更准确——它不响应 summary 内部子元素的点击,也不受冒泡干扰。
document.querySelector('details').addEventListener('toggle', (e) => {
console.log('当前是否展开:', e.target.open);
});
- 该事件在用户操作或 JS 设置
open属性时都会触发 - 不要在
toggle里调用e.preventDefault()——它没有默认行为可阻止 - 若需兼容 IE 或极老浏览器,得回退到手写
div+aria-expanded+ JS 切换 class,但已非常少见
列表项太多时,注意 details 不会懒加载内容
details 只控制可见性,内部所有 HTML 都会在页面加载时解析并渲染(即使未展开)。如果折叠区包含大量图片、iframe 或复杂组件,首屏性能会受影响。
- 真实场景中,展开前就该存在的 DOM 才放进去;动态加载内容请用 JS 在
toggle事件中 fetch 并插入 - 不要指望
details替代虚拟滚动或分页逻辑 - 用
getComputedStyle(details).display === 'none'判断是否隐藏没意义——它始终是block,靠的是open属性和 UA 样式控制显隐
最易被忽略的是语义与可访问性平衡:过度嵌套 details 会让屏幕阅读器用户迷失层级,而纯视觉美化又可能破坏默认键盘导航(如空格/回车触发展开)。留出明确视觉反馈,比追求“完全自定义”更重要。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











