details标签原生支持折叠/展开,需包含summary子元素,默认收起内容,添加open属性可默认展开;自定义样式需重置list-style并用::marker控制箭头;兼容IE需JS降级。

details标签的基本用法和默认行为
details 标签原生支持折叠/展开,不需要 JavaScript 就能工作。它默认收起内容,点击 summary 元素触发切换。浏览器会自动添加小三角指示器(部分浏览器可自定义样式),且自带 ARIA 属性(如 aria-expanded),语义和可访问性比手写 div + JS 更可靠。
常见错误是直接写 <details>内容</details> 却没加 <summary> —— 这会导致内容始终可见,且无标题、无交互区域。正确结构必须包含 <summary> 作为第一个子元素:
<details> <summary>点击展开说明</summary> <p>这里是被折叠的详细内容。</p> </details>
如何让details默认展开
加 open 属性即可,这是布尔属性,有即生效:
<details open> <summary>默认已展开</summary> <p>页面加载时就显示。</p> </details>
注意:open 是初始状态,用户手动收起后不会重置;想“每次刷新都展开”,只写 open 就够了;想“强制保持展开”(禁用收起),得配合 CSS 或 JS 拦截 toggle 事件——但这样破坏了原生语义,不推荐。
立即学习“前端免费学习笔记(深入)”;
容易踩的坑:
-
open="false"无效 —— 布尔属性不存在 “false 值”,写了也等同于open - 服务端渲染时若动态控制
open,需确保前后端一致,否则可能闪动
自定义summary样式和移除默认箭头
默认箭头由浏览器 UA 样式控制,不同浏览器位置和形状不同(Chrome 在左,Firefox 在右)。要统一或隐藏,必须重置 summary 的 list-style 并处理伪元素:
details summary {
list-style: none;
}
details summary::marker {
content: "▶ ";
}
details[open] summary::marker {
content: "▼ ";
}
关键点:
-
::marker是标准方式,但 Safari 15.4+ 才完全支持,旧版需用appearance: none+ 自定义背景图或 Unicode 字符 - 不要对
summary设display: block以外的值(如flex),否则可能破坏点击热区 - 如果用 JS 动态插入
details,记得在插入后调用element.setAttribute('open', '')才能触发渲染
监听展开/收起状态变化
原生提供 toggle 事件,只在用户点击触发时派发(JS 修改 open 属性不会触发):
document.querySelector('details').addEventListener('toggle', (e) => {
console.log('当前是否展开:', e.target.open);
});
性能与兼容性提醒:
- IE 完全不支持
details,Edge 15+ 支持;如需兼容 IE,必须降级为 JS 实现,不能仅靠 CSS -
toggle事件无法阻止默认行为(比如你想禁止收起),只能读取状态后做后续逻辑 - 多个
details共存时,别用querySelector取第一个了事,应遍历或委托事件
真正麻烦的是动画:details 内容高度是自动计算的,CSS transition: height 无法从 auto 动画,得用 max-height 模拟,或改用 clip-path / transform。这些方案都会绕过原生行为,得自己维护 open 状态和 ARIA 属性——一旦漏掉,可访问性就垮了。



















