<details>标签原生支持折叠交互,无需JavaScript;<summary>必须为首个子元素,加open属性可默认展开;支持键盘操作与屏幕阅读器,IE不支持,现代浏览器均兼容。

HTML <details> 标签本身就能实现折叠交互,无需 JS
直接用原生 <details> + <summary> 就能完成基础折叠面板,浏览器原生支持,语义清晰,还自带 ARIA 属性(如 aria-expanded),无障碍友好。Chrome、Firefox、Safari(12.1+)、Edge 全支持,IE 完全不支持——如果必须兼容 IE,得降级为 JS 实现,但现代项目基本可忽略。
常见错误是把 <summary> 写成自闭合标签(<summary />),这会导致内容无法展开;或者把其他元素(比如 <p>)直接塞进 <details> 里却不包裹在 <summary> 后——<summary> 必须是 <details> 的第一个子元素。
-
<details>默认收起,加open属性可默认展开:<details open> -
<summary>内容会显示为折叠标题,点击触发切换;它后面的所有同级内容(文本、<div>、<table>等)都会被折叠/展开 - 不能嵌套
<details>在<summary>里(会破坏语义和行为),但可以嵌套在<details>的主体内容中
用 CSS 控制样式时,summary::marker 和 details[open] 是关键钩子
原生 <details> 的三角图标是 UA 样式,不同浏览器表现不一(比如 Safari 显示右向箭头,Chrome 是下拉小三角)。要统一外观或替换图标,得覆盖 summary::marker,并禁用默认 marker:
summary {
list-style: none;
}
summary::marker {
content: "▶ ";
color: #666;
}
details[open] > summary::marker {
content: "▼ ";
}注意:Firefox 目前不支持 summary::marker,需用 summary::before 模拟;若需完全一致的图标,推荐用字体图标或 SVG 内联替代。
- 不要用
display: none隐藏<summary>,否则会丢失可访问性(屏幕阅读器读不到) - 想禁用点击展开行为?别删
<summary>,而是加pointer-events: none并用 JS 手动控制open属性 -
details[open] > *可以选中展开后显示的所有子元素,适合做动画过渡(但原生不带动画,需配合max-height或height过渡)
需要平滑展开动画?得绕过原生限制,用 max-height + CSS 过渡
<details> 本身不支持 CSS transition,因为 height: auto 无法过渡。常见解法是用 max-height 模拟:设一个足够大的固定值(如 max-height: 500px),再对 max-height 做过渡。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
示例结构:
<details class="animated"> <summary>点我展开</summary> <div class="content">这里是长内容...</div> </details>
CSS:
.animated .content {
overflow: hidden;
max-height: 0;
transition: max-height 0.3s ease-out;
}
.animated[open] .content {
max-height: 500px; /* 需大于内容实际高度 */
}- 这个方案依赖预估高度,内容动态变化(比如字体缩放、响应式断点)时可能出错;更健壮的做法是用 JS 测量真实
scrollHeight后设置max-height - 动画只适用于内容高度可控的场景;含 iframe、video 或未加载图片时,
scrollHeight可能不准 - 若用 JS 控制,建议监听
toggle事件而非click,因为用户也可能通过键盘(空格/回车)触发
与 JavaScript 交互时,优先监听 toggle 事件而不是 click
<details> 元素会触发 toggle 事件(每次展开/收起都触发),比监听 <summary> 的 click 更准确、更语义化,也兼容键盘操作。
document.querySelectorAll('details').forEach(el => {
el.addEventListener('toggle', () => {
console.log('当前状态:', el.open);
// 可在这里加载异步内容、打点统计、触发动画等
});
});-
toggle事件没有取消机制(preventDefault()无效),如需阻止展开,只能提前控制open属性(比如根据条件手动设回false) - 不要在
toggle回调里直接修改el.open,否则可能引发循环触发 - 服务端渲染(SSR)时,若初始状态由 JS 控制,记得同步设置
open属性,避免水合(hydration)时状态不一致
细节折叠看似简单,但跨浏览器样式一致性、动画高度估算、键盘可访问性、以及 SSR 水合时机这几个点,最容易在上线后暴露问题。

















