直接用 <details> 和 <summary> 可构建语义清晰、无需 JS 的折叠问答组件,天然支持无障碍访问、键盘操作与 SEO;每个问答独立封装,<summary> 必为首个子元素,答案紧随其后,可含任意 HTML;禁用 open 属性滥用,推荐 CSS 定制图标与交互反馈;手风琴效果需 JS 监听 toggle 事件实现单开。

直接用 <details> 和 <summary> 就能构建语义清晰、无需 JavaScript 的折叠问答组件。它们天然适配屏幕阅读器,支持键盘操作(空格/回车切换),且搜索引擎能识别其问答结构。
基础结构与语义规范
每个问答项应独立封装为一个 <details>,<summary> 必须是它的第一个子元素,里面放问题文字;其余内容(答案)紧跟其后。
- 问题文本要简洁明确,避免“点击查看”这类无意义提示,直接写问题本身,例如“退款流程需要多久?”
- 答案区域可包含任意合法 HTML:段落、列表、代码块、图片甚至嵌套的
<details>(需注意浏览器兼容性) - 不要在
<summary>内放置<button>、<input>等交互元素,否则可能中断原生行为
默认展开与初始状态控制
多数 FAQ 场景下,所有项默认收起更合理;但若需突出某条高频问题,可对对应 <details> 添加 open 属性。
<details open><summary>为什么注册失败?</summary><p>请检查邮箱格式和网络连接。</p></details>- 避免滥用
open—— 页面加载时过多展开会增加首屏渲染压力,也削弱了折叠设计的初衷
样式定制与视觉优化
原生箭头样式不统一,建议用 CSS 伪元素统一替换,同时增强可点击反馈。
立即学习“前端免费学习笔记(深入)”;
- 清除默认标记:
summary { list-style: none; } - 添加自定义图标:
summary::before { content: "▶"; margin-right: 6px; transition: transform 0.2s; } - 展开时旋转图标:
details[open] > summary::before { content: "▼"; transform: rotate(90deg); } - 提升可点击感:给
summary加上cursor: pointer、轻微背景色或下划线
手风琴效果(单开模式)实现
原生不支持自动收起其他项,需用 JavaScript 监听 toggle 事件手动处理。
- 只在当前项展开时,遍历同级所有
<details>,移除它们的open属性 - 监听代码示例:
document.querySelectorAll('.faq-item').forEach(el => el.addEventListener('toggle', () => { if (el.open) { document.querySelectorAll('.faq-item').forEach(other => other !== el && other.removeAttribute('open')); } })); - 关键点:必须用
toggle事件而非click,确保获取的是真实更新后的状态



















