summary必须是details的直接且首个子元素,否则失效;默认不展开需用open布尔属性;监听用toggle事件;无障碍需防文本重复朗读;样式定制应避免破坏原生箭头和语义。

summary 元素必须作为 details 的第一个子元素
summary 不是独立可用的标签,它只在 details 内部生效,且必须紧接在 details 开始标签之后。如果中间插入了空格、注释或任何其他元素(哪怕只是 ),浏览器会自动忽略它,导致点击无反应或显示为普通文本。
常见错误现象:
– 点击标题没反应,展开内容始终可见
– 控制台无报错,但 summary 渲染成纯文本,不带小三角图标
– 在 Safari 中完全不触发折叠逻辑
- 确保
summary是details的**直接且首个子节点** - 避免在
<details><summary></summary></details>之间写换行或空格(虽然部分浏览器容忍,但 Safari 严格) - 不要用 CSS 把
summary设置为display: block或覆盖list-style,这会干扰原生箭头渲染
details 默认展开要用 open 属性,不能靠 JS 模拟
想让折叠块默认打开,必须显式写 open 布尔属性:<details open><summary>标题</summary>...</details>。仅用 JS 设置 details.open = true 或添加 open 类名都无效——浏览器只认原生属性是否存在。
使用场景:
– 页面加载时需默认展开 FAQ 第一项
– 后端模板根据状态动态输出 open 属性
– SSR 渲染中避免水合后闪烁(JS 补开会导致内容先收再展)
立即学习“前端免费学习笔记(深入)”;
-
open是布尔属性,写open=""、open="open"或open="true"效果一致,推荐简写open - 移除
open属性即关闭,用removeAttribute('open'),不是设为false - 监听展开/收起用
toggle事件,不是click:details.addEventListener('toggle', () => { ... })
summary 里的内容会被读屏器朗读两次
这是实际无障碍测试中高频出现的问题:summary 文本既作为可点击控件被朗读一次,又在展开后作为内容一部分再被朗读一次。对视障用户造成冗余干扰。
原因在于,浏览器把 summary 同时视为控件(control)和内容(content),而 ARIA 规范建议控件文本不应重复出现在其控制的内容里。
- 解决方案:在
summary内用aria-hidden="true"隐藏文字,再用aria-labelledby让内容区关联一个不可见的标题 ID - 更轻量做法:保持结构简洁,确认内容区首句不重复
summary文本(例如 summary 写“配置说明”,内容开头别再写“配置说明:……”) - 不要给
summary加role="button"——它已经是可访问按钮,加了反而破坏语义
样式定制要绕过 user-agent 样式重置
各浏览器对 summary 有强默认样式(如 Chrome 强制 list-style: none + 小箭头伪元素),直接写 summary { font-weight: bold; } 可能失效,尤其箭头图标消失或错位。
性能影响:过度用 ::marker 或 ::before 覆盖原生箭头,可能触发重排;Safari 对 summary::marker 支持不稳定。
- 改字体、颜色、padding 安全,但避免动
display、margin(尤其左右 margin) - 自定义箭头建议用
summary::after+content: "▶",并配合details[open] summary::after { content: "▼"; } - 禁用原生箭头统一写法:
summary::-webkit-details-marker { display: none; }(Chrome/Safari),Firefox 需额外处理summary::marker { display: none; }
summary 语义边界的理解差异——有的当控件,有的当标题,有的连 toggle 事件都不抛。动手前先在 Safari、Firefox、Edge 里点三遍,比查文档管用。


















