details标签不支持summary嵌套,合法结构是嵌套details元素,每层仅一个summary作为直接子元素;嵌套过深需注意safari兼容性、视觉缩进与表单干扰问题。

details 标签本身不支持嵌套 summary ——这是个常见误解。真正合法且稳定的树形导航结构,是嵌套 details 元素,每个层级用一个 summary 作为其**直接子元素**,而不是把 summary 套在另一个 summary 里。
为什么不能在 summary 里再放 summary
HTML 规范明确要求:summary 必须是 details 的第一个**直接子元素**。如果写成 <summary><summary>子项</summary></summary>,浏览器会视作无效嵌套,导致:
- 第二个 summary 失去交互能力(点不动、键盘不可聚焦)
- 语义断裂,屏幕阅读器可能跳过或误读
- 所有现代浏览器(包括 Safari 17+)都会静默降级,不报错但也不工作
嵌套 details 是合法且推荐的写法
多级分类导航的正确结构是:外层 details → 内层 details → 再内层 details,每层只配一个 summary。例如:
<details><summary>前端</summary><details><summary>HTML</summary><p>语义化标签</p><div class="aritcle_card flexRow artxards"> <div class="artcardd flexRow"> <a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill4293" title="Doc To HTML"><img src="https://img.php.cn/upload/skill/000/000/081/178998486916110.jpg" alt="Doc To HTML" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a> <div class="aritcle_card_info flexColumn"> <a rel="nofollow" href="/xiazai/skill4293" title="Doc To HTML" class="overflowclass">Doc To HTML</a> <p class="overflowclass">使用 MinerU 文档处理引擎将 Word 文档(.doc、.docx)转换为保留结构和格式的干净 HTML。</p> </div> <a rel="nofollow" href="/xiazai/skill4293" title="Doc To HTML" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div> </details><details><summary>CSS</summary><p>Flex 布局</p> </details></details>
这种写法:
- 符合 WHATWG 规范,所有 Chrome 12+ / Firefox 49+ / Safari 6+ / Edge 79+ 均原生支持
- 每个 summary 保持可键盘操作(Tab 进入、Space/Enter 触发)
- toggle 事件能准确捕获每一层的状态变化
- 不依赖 JS 就能记住各层独立展开/收起状态(浏览器原生行为)
嵌套超过 2 层时的实际限制
虽然规范允许任意深度嵌套,但真实场景中要注意:
- Safari(尤其是 iOS 15.4 之前)对 >2 层嵌套的 toggle 事件触发不稳定,可能漏掉某一层的状态变更
- 超过 3 层后视觉缩进易混乱,用户难以分辨归属关系;建议用 CSS 控制 padding-left 或 margin-inline-start 统一缩进,而非靠嵌套层数“撑”出结构
- 不要把整个导航树塞进一个 form 标签里:旧版 Safari 和部分 EdgeHTML 版本会错误地将 summary 当作表单控件,导致提交时意外包含空值
自定义图标和样式必须保留原生交互逻辑
想替换默认小三角?别用 list-style: none + summary::before 粗暴覆盖——Safari 16.4 以下根本不支持 ::marker,而强行移除原生 marker 会导致:
- 键盘用户无法感知该元素是可交互的(无障碍失效)
- 部分安卓 WebView 中点击热区缩小甚至消失
- 更稳妥的做法是:summary::marker { content: "▸"; }(仅 Safari 16.4+ 支持),配合 summary:focus-visible { outline: 2px solid #007aff; } 保证焦点可见性
- 如果必须兼容老 Safari,用 SVG 内联图标 + display: inline-flex 布局,但务必保留 summary 的原生 role="button" 语义(不要加 role 覆盖)
最常被忽略的一点:嵌套结构里,open 属性只作用于当前 details 元素,不会影响子级;而 JS 设置 el.open = true 后再手动点击,某些 Safari 版本会重置状态异常——所以静态导航优先用 HTML open 属性控制初始态,动态交互统一走 JS 管理,二者别混用。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










