details标签原生支持折叠展开,但需严格遵循summary为首个子元素、禁用干扰css、用::before替代::marker、js操作open属性、旧浏览器需polyfill等规范。

details 标签本身就能实现折叠展开,不需要 JS,但点不动、样式错位、Safari 默认展开关不掉——这些问题基本都出在结构或 CSS 干预上。
details 和 summary 的嵌套顺序不能错
summary 必须是 details 的第一个子元素,且不能被 <p></p>、<div> 等块级标签包裹。否则 Safari 和旧版 Chrome 会忽略点击逻辑,表现为“点了没反应”。
<ul>
<li>✅ 正确:<code><details><summary>标题</summary><p>内容</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill8961" title="html-to-pptx-converter"><img
src="https://img.php.cn/upload/skill/000/000/081/179232667384043.jpg" alt="html-to-pptx-converter" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill8961" title="html-to-pptx-converter" class="overflowclass">html-to-pptx-converter</a>
<p class="overflowclass">使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。</p>
</div>
<a rel="nofollow" href="/xiazai/skill8961" title="html-to-pptx-converter" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div></details>
<details><p><summary>标题</summary></p>
<p>内容</p></details>
summary 内部不要用 display: inline-block 或 float,会破坏原生触发区域自定义箭头图标要用 ::before,别碰 ::marker
::marker 在旧版 Safari(≤15.6)和部分 Edge 中不生效,::-webkit-details-marker 又只限 WebKit。统一用 summary::before 加 content 最稳。
- 隐藏原生箭头:
summary::marker { display: none; }(仅现代浏览器有效) - 补图标(兼容写法):
summary::before { content: "▶"; margin-right: 6px; transition: transform .2s; } - 展开时旋转:
details[open] > summary::before { transform: rotate(90deg); }
JS 控制要改 open 属性,别操作 display
直接改 style.display 会绕过浏览器内置状态,导致 toggle 事件不触发、键盘焦点异常、屏幕阅读器无法识别。
- ✅ 正确切换:
el.open = !el.open或el.toggleAttribute('open') - ✅ 监听状态变化:
el.addEventListener('toggle', () => console.log(el.open)) - ❌ 错误写法:
el.style.display = el.style.display === 'none' ? 'block' : 'none' - ⚠️ 注意:给
details绑onclick会触发两次——一次原生,一次你写的,容易重复执行
IE 和老 Edge 需要 polyfill,不是加个 class 就能兼容
details 在 IE 完全不支持,Edge 12–18 虽支持但无动画、toggle 事件不可靠。如果项目必须跑在这些环境里,polyfill 是刚需,不是靠 CSS 模拟就能糊弄过去。
- 推荐用
details-polyfill(npm 包),加载后自动降级为 JS 控制的max-height动画 - 手动模拟时,别用
height: 0 / auto切换——CSS 过渡不认这个,得用max-height+scrollHeight计算 - 无障碍方面:
summary天然支持键盘Enter/Space触发,但 polyfill 后需手动补aria-expanded和aria-controls
最常被忽略的是:哪怕只是加了一行 summary { display: flex; },也可能让 Safari 的点击热区偏移或失效——原生行为比想象中更脆弱,动之前先测 Safari 和 VoiceOver。










