summary必须是details的直接子元素,否则失效;只能有一个,内容限纯文本、inline元素;标题须写在标签内,不可嵌套块级元素或依赖属性;图标用::marker或::before,需兼顾兼容性与无障碍。

summary 必须是 details 的第一个直接子元素
不满足这个结构,标题就点不动,甚至被浏览器忽略。它不是“写在哪都行”的标签,而是语义和交互强绑定的组件。
常见错误包括:<details><p>说明</p><summary>标题</summary></details>——中间插了 <p>,summary 就失效;或者开头有换行、空格文本节点,Safari 就可能丢焦点。
- 正确写法只有一种:
<details><summary>标题文本</summary><p>折叠内容</p></details> -
summary不能嵌套在<div>、<span>或其他标签里,必须是details的直接子节点 - 一个
details只能有一个summary;多写第二个会被当普通文本,不触发折叠
标题文案要直接写在 summary 标签内,不能用属性或嵌套块级元素
summary 的可见文字就是它的文本内容,不是 title 属性,也不是子标签。写错位置,文字就不显示,或语义断裂。
比如 <summary title="API文档"></summary> 完全无效;<summary><div>API文档</div></summary> 会被浏览器修正为 <summary></summary><div>API文档</div>,标题消失。
立即学习“前端免费学习笔记(深入)”;
- 允许的内容:纯文本、
<strong>、<code>、emoji(如 ▶️)、<svg>(需 inline) - 禁止的内容:
<p>、<div>、<ul>等块级元素 - 动态更新标题时(如展开后改为“收起”),必须直接修改
summary.textContent,不能只改aria-label
自定义箭头要用 summary::marker,但 Safari 旧版得备选
浏览器默认用小三角图标,想换图标必须靠 summary::marker,但它的兼容性有坑:Safari 15.4 之前不支持,部分 Chrome 版本对 content 赋值不稳定。
最稳妥写法是先清空原生图标,再用 ::before 补图标:
summary::marker {
content: "";
}
summary::before {
content: "▶";
margin-right: 4px;
}
details[open] > summary::before {
content: "▼";
}
- 别写
summary::marker { display: none; }——这会让部分读屏软件丢失状态提示 - 如果项目要兼容 iOS 15.3 及更早版本,必须用
::before方案,且避免依赖::marker - 图标语义不能丢:用 “▶” 表示可展开,“▼” 表示已展开,不能只靠颜色区分
键盘操作和无障碍不能被 CSS 或 JS 破坏
summary 原生支持空格键和回车键切换状态,这是无障碍底线。很多样式改动或事件绑定会悄悄关掉它。
典型破坏行为:summary { pointer-events: none; }、给 summary 绑 onclick 并调 event.preventDefault()、或设 tabindex="-1"。
- 验证是否还可用键盘操作:聚焦
summary后按空格/Enter,看是否切换展开 - 若需定制焦点样式,同时写
summary:focus和summary:focus-visible,否则 Chrome/Firefox 表现不一致 - 移动端点击热区太小?用
padding扩展,别靠width: 100%或伪元素撑宽——iOS Safari 上常失效



















