<details>和<summary>是实现语义化、可访问、免JS的FAQ最佳方案,原生支持键盘操作与屏幕阅读器,需确保<summary>为<details>首子元素且双标签闭合,配合:target与脚本实现锚点展开,并优化移动端点击热区与视觉断层。

<details> 和 <summary> 是当前最直接、最可靠的方案,不需要 JavaScript 就能实现语义正确、可访问、可 SEO 的 FAQ 页面。
为什么不用 JS 或 <dl> 写 FAQ
手写 JS 折叠逻辑容易漏掉 aria-expanded、焦点管理或空格键支持,导致屏幕阅读器无法识别状态变化;<dl> 虽语义清晰,但天生无交互能力,加折叠就得补一堆 ARIA 和脚本,反而增加出错概率。而 <details> 浏览器原生支持展开/收起、键盘操作(Tab 进入、Space 切换)、屏幕阅读器播报,Chrome 12+、Firefox 49+、Safari 6.1+、Edge 79+ 全部支持,IE11 是唯一例外——但如今已无必要兼容。
<summary> 必须是 <details> 的第一个子元素
这是最容易翻车的点:如果中间插了空格、注释、<p> 或 <h3>,点击就失效。常见错误写法:<details><p><summary>Q: …</summary></p><p>A: …</p></details> —— 这里 <p> 挡在了 <summary> 前面,折叠功能直接挂掉。
- 正确结构必须是:
<details><summary>问题文本</summary><p>答案内容</p></details> -
<summary>必须双标签,不能写成自闭合形式(如<summary />) - 避免在
<summary>内包裹块级元素(<div>、<h3>),可用<strong>或<span>替代
如何让 URL 锚点自动展开对应 FAQ
用户从邮件或搜索结果点进 faq.html#forgot-password,浏览器默认只滚动,不展开。要让它生效,得靠两层保障:
立即学习“前端免费学习笔记(深入)”;
- 每个
<details>加唯一id,例如<details id="forgot-password"> - CSS 中写
details:target { open: true; }(注意:Safari 15.4+ 才完全支持该规则的open设置) - 为兜底兼容旧 Safari,加一行极简脚本(非必需但推荐):
const id = location.hash.slice(1);<br>const el = document.getElementById(id);<br>if (el && el.tagName === 'DETAILS') el.open = true;
ID 值不能含空格或中文标点;若需从中文标题生成 ID,建议转小写拼音或用 encodeURIComponent() 处理后再截取。
移动端点击区域小、误触收起怎么修
原生 <summary> 默认热区只覆盖文字本身,手机上一点就偏,滑动时还容易误触发收起。这不是 bug,是浏览器设计如此——它把整个 <summary> 元素当按钮,但默认 padding 和 line-height 太小。
- 给
<summary>加padding: 12px 16px,并设cursor: pointer明确提示可交互 - 加
user-select: none防止长按选中干扰操作(不影响屏幕阅读器) - 绝对不要设
display: block或width: 100%,否则右侧空白处也能触发收起,体验反向恶化 - 记得设
details { scroll-margin-top: 80px; },否则scrollIntoView()定位后会被固定头部遮住
真正难处理的是“展开后内容不可见”这类视觉断层——比如用了 overflow: hidden 在 <details> 上,会裁掉 <summary> 的下边框或阴影,看起来像断裂了一样。这点常被忽略,但直接影响专业感。



















