<details>是轻量语义化FAQ方案,但需严守结构约束(<summary>须为首个唯一子元素)、用details:target或JS实现锚点展开、扩大移动端点击区、以clip-path实现动画,并兼顾可访问性与兼容性。

<details> 是目前最轻量、语义正确且无需 JS 就能工作的 FAQ 方案,但直接套用容易在锚点跳转、动画、移动端点击区域和 Safari 兼容性上翻车。
details + summary 必须满足的 HTML 结构约束
浏览器只认严格结构:<summary> 必须是 <details> 的**第一个且唯一子元素**,后面才能跟内容。嵌套 <h3>、<p> 或多个 <summary> 会触发渲染异常或交互失效。
- ✅ 正确写法:
<details><summary>问题标题</summary><p>答案内容</p></details> - ❌ 错误写法:
<details><div><summary>…</summary></div><p>…</p></details>(<summary>不再是首子元素) - ❌ 错误写法:
<details><summary>Q1</summary><summary>Q2</summary><p>…</p></details>(多个<summary>) - 默认收起;加
open属性可默认展开:<details open>
让 URL 锚点自动展开对应 FAQ 条目
用户点击 faq.html#how-to-reset 时,浏览器不会自动设 open=true —— 这是原生限制,必须靠 details:target CSS 或极简脚本补全。
- CSS 方案(推荐,兼容 Chrome/Firefox):
details:target { open: true; },前提是每个<details>有匹配的id,如<details id="how-to-reset"> - Safari 15.4 以下不支持
details:target { open: true },需加一行 JS:document.getElementById(location.hash.slice(1))?.setAttribute('open', '') - ID 值不能含空格或中文;建议用小写拼音或
encodeURIComponent()处理后截取,例如 “忘记密码?” →id="forgot-password"
移动端点击区域太小、误触收起怎么修
原生 <summary> 默认热区仅覆盖文字本身,在手机上极易点不准或滑动误触发。这不是 bug,是设计缺陷,必须手动扩大。
立即学习“前端免费学习笔记(深入)”;
- 给
<summary>加padding: 12px 16px,并设cursor: pointer明确提示可交互 - 加
user-select: none防止长按选中文本干扰操作(不影响屏幕阅读器) - 禁止
display: block或width: 100%—— 它会让右侧空白区域也能触发收起,破坏体验 - 避免用
appearance: none或粗暴清空list-style,否则可能丢失焦点样式和键盘支持
用 clip-path 做展开动画,别碰 height
<details> 的 open 是布尔属性,无法直接过渡;用 height 动画会因内容高度动态变化导致抖动、计算错误或布局重排。
- 稳妥方案是用
clip-path:details summary ~ * { clip-path: inset(0 0 100% 0); transition: clip-path 0.25s ease; }+details[open] summary ~ * { clip-path: inset(0); } - 不要给
<details>设overflow: hidden—— 它会裁掉<summary>下边框或阴影,造成视觉割裂 - 若内容高度固定,可用
max-height+transition,但需预估足够大的值,否则动画会卡顿 -
@starting-style目前仅 Chrome 119+ 支持,生产环境慎用
真正难的不是写出来,而是让每个细节都经得起键盘导航、屏幕阅读器识别、URL 分享跳转和手指误触——<details> 看似简单,但语义、可访问性和行为一致性必须同步守住。



















