summary必须是details的首个直接子元素,禁嵌交互元素,不支持原生动画,需手动实现过渡并确保无障碍支持。
否则浏览器会自动忽略它,或把内容渲染成普通文本而非折叠控件。Chrome、Firefox 和 Safari 都严格遵循这一规则,哪怕中间只夹了一个空格或换行符,summary 的点击展开功能都会失效。
实操建议:
<summary> 是 <details> 的直接子节点,且排在最前<details><div>...</div><summary>标题</summary></details></li><li>正确写法是:<code><details><summary>标题</summary><p>内容</p></details></li><li>如果要用 CSS 控制样式,优先通过 <code>details > summary选择器定位,而不是依赖 class 或 id
HTML 规范明确禁止在 summary 中放置可聚焦或可激活的元素。一旦嵌入,部分浏览器(尤其是 Safari)会直接禁用整个 summary 的展开/收起行为,且控制台不报错,极难排查。
常见错误现象:
立即学习“前端免费学习笔记(深入)”;
<summary>配置项 <button>重置</button></summary> —— 点击按钮无效,点击文字也不再切换状态<summary><a href="#">帮助</a></summary> —— 整个 summary 失去 toggle 功能替代方案:
summary 外部,比如放在 details 内容区顶部aria-label 或 title 提供辅助信息,而非可点击链接open 属性,绕过原生 summary 的限制原生 details 切换时是瞬间显示/隐藏,没有高度过渡效果。直接对 details > *:not(summary) 加 transition: max-height .3s 不生效,因为内容区没有固定高度,max-height 无法插值。
可行做法(无需第三方库):
toggle 事件,在 JS 中手动设置 max-height 和 overflow
is-open),配合 CSS @keyframes 做 height 动画(需预估最大高度)height: auto + getBoundingClientRect() 动态计算并设置内联 max-height
details[open] > * 的 CSS 选择器支持较晚(iOS 15.4+),旧版本需降级处理屏幕阅读器靠 summary 的文本内容识别可折叠区域,同时根据 details 是否带 open 属性判断当前状态。如果用 JS 操作但忘了同步更新属性,或 summary 为空,读屏软件就会跳过该区域或误报“不可操作”。
关键点:
display: none 隐藏 summary —— 这会让整个 details 对读屏器不可见element.open = true/false,而不是只改 classsummary 的位置、内容纯度、状态同步,每一步都卡在规范边界上。稍有偏离,用户看到的可能只是段静止的文字。