details + summary 是最简稳的 faq 折叠结构,原生支持无障碍、键盘操作和 seo,但需严格遵循嵌套规则:summary 必为 details 唯一直接子元素,不可包裹于 div 或 heading 中,且不支持嵌套。

details + summary 是当前最简、最稳的 FAQ 折叠结构,不需要 JS 就能支持展开/收起、键盘操作和屏幕阅读器,但必须写对顺序和嵌套规则。
为什么不能用 div + JS 模拟折叠
手写 JS 控制 display 或 hidden 会立刻掉进三个坑:一是必须手动补全 aria-expanded、aria-controls 和焦点管理,漏一项就对键盘或读屏用户不友好;二是动画若用 height 过渡,内容高度动态时容易抖动或截断;三是搜索引擎可能无法索引默认隐藏的内容——除非你确保服务端已渲染全部 HTML。而 details 原生就处理了这些。
-
details在 Chrome 12+、Firefox 49+、Safari 6.1+、Edge 79+ 全支持,IE 不支持但可优雅降级为全部展开 - 它自动绑定空格/回车切换、Tab 键聚焦、屏幕阅读器播报“已折叠/已展开”
- 不支持嵌套——
details里面不能再套details,旧版 Safari 会失效
summary 必须是 details 的第一个且唯一子元素
这是最容易翻车的地方。写成 <details><div><summary>Q?</summary></div>
<p>A</p></details> 或 <details><h3><summary>Q?</summary></h3>
<p>A</p></details> 都会导致点击无反应,因为浏览器只认直接子级的 summary。
- 正确结构只能是:
<details><summary>问题文本</summary><p>答案内容</p><div class="aritcle_card flexRow artxards"> <div class="artcardd flexRow"> <a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill5030" title="Html To Pdf"><img src="https://img.php.cn/upload/skill/000/000/081/179031962213835.jpg" alt="Html To Pdf" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a> <div class="aritcle_card_info flexColumn"> <a rel="nofollow" href="/xiazai/skill5030" title="Html To Pdf" class="overflowclass">Html To Pdf</a> <p class="overflowclass">使用 Puppeteer + Chrome 将 HTML 渲染为中文 PDF,自动处理图表等待、Tab 展开、动画、测高、白边消除、防分页,适用于看板、报表、网页和交互图表转 PDF。</p> </div> <a rel="nofollow" href="/xiazai/skill5030" title="Html To Pdf" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div></details> -
summary内部可用<strong></strong>或<span></span>加粗关键词,但不能塞<div>、<code><h3></h3>等块级标签 - 别给
summary加role="button"——它本来就是可交互元素,加了反而干扰读屏逻辑 - CSS 方案(推荐):
details:target { open: true; },注意 Safari 15.4+ 才完全支持,旧版需兜底 - JS 补漏(一行就够):
document.getElementById(location.hash.slice(1))?.open = true;,放在底部或 DOMContentLoaded 后执行 - ID 值必须合法:不能含空格、中文、特殊符号;建议用小写连字符,如
id="login-timeout" - 别在
summary上设tabindex="-1"——这会让键盘用户跳过整个 FAQ 条目 - 必须用
WebPage作为外层类型,再通过mainEntity指向Question,不能直接用FAQPage作顶层 -
name和acceptedAnswer.text必须是纯文本,不能带<p></p>、<strong></strong>标签,否则 JSON-LD 解析失败 - 所有字段值要用
JSON.stringify()处理,避免引号、换行导致语法错误 - Schema 必须放在
或页面顶部的<script type="application/ld+json"></script>中
如何让 URL 锚点自动展开对应 FAQ
用户点击 help.html#payment-failed,浏览器应该滚动到那个条目并展开它。原生 details 不会自动响应 hash,得靠 :target 伪类或极简脚本。
结构化数据怎么配才被 Google 当作 FAQ 富文本
光有 details 结构,Google 不会识别为 FAQ 卡片。必须加 FAQPage Schema,而且格式错一点就白搭。
最常被忽略的是:页面上改了 FAQ 文本,但头部的 JSON-LD 没同步更新。Google 明确要求结构化数据必须与可见内容严格一致,脱节就失去富文本资格。










