是目前最轻量、语义正确、无需JS且无障碍友好的二级菜单方案,原生支持嵌套,Chrome/Firefox/Safari(≥16.4)行为一致;嵌套需满足结构约束:子必须是父元素的直接子元素,必须为首个子元素,内容须紧随同级放置;CSS应禁用原生marker并用伪元素统一绘制图标,缩进用padding-left,且必须手动设置aria-controls与id以保障无障碍。

用 <details><summary></summary></details> 实现二级菜单折叠展开,是目前最轻量、语义正确、无需 JS 且无障碍友好的方案。它原生支持嵌套,Chrome/Firefox/Safari(≥16.4)行为一致,不用 polyfill,也不用自己管理 open 状态。
为什么不用 display: none + JS 切 class?
手动控制 display 或 visibility 容易踩坑:比如忘记移除旧状态导致多个子菜单同时展开;键盘焦点丢失;屏幕阅读器无法感知展开状态;移动端 touch 事件处理复杂。而 <details></details> 自带 open 属性、aria-expanded、Enter/Space 切换逻辑,浏览器已做兼容性兜底。
<details></details> 嵌套必须满足的结构约束
嵌套失效的常见原因是 HTML 结构不合规:
- 子
<details></details>必须是父<details></details>的直接子元素,不能包在<div> 或 <code><p></p><div class="aritcle_card flexRow"> <div class="artcardd flexRow"> <a class="aritcle_card_img" href="/xiazai/skill10246" title="HTML Text Extract"><img src="https://img.php.cn/upload/skill/001/246/273/6adaf20dee630206.jpg" alt="HTML Text Extract" ></a> <div class="aritcle_card_info flexColumn"> <a href="/xiazai/skill10246" title="HTML Text Extract">HTML Text Extract</a> <p>从HTML页面(URL、文件或标准输入)中提取主体内容文本,去除导航、页脚、广告和模板文本。可直接传递给readability_check或其他文本工具。</p> </div> <a href="/xiazai/skill10246" title="HTML Text Extract" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div>里 -
<summary></summary>必须是<details></details>的第一个子元素 - 子菜单内容要放在
<summary></summary>后面、同级闭合前,例如:<details> <summary>一级</summary> <p>平级说明</p><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/cb6835dc7db1" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">前端免费学习笔记(深入)</a>”;</p> <details><summary>二级</summary></details> <!-- ✅ 正确 --> </details>
- 禁用原生 marker:
summary::-webkit-details-marker { display: none; }+summary::marker { content: "" } - 用
summary::before绘制 ▼/▶ 图标,配合details[open] summary::before切换 - 每级缩进用
padding-left(别用margin-left,否则点击热区偏移) - 为每个子内容区加唯一
id,并在对应<summary></summary>上写aria-controls="xxx",否则 NVDA/JAWS 读不出控制关系
CSS 控制图标、缩进与无障碍补全
浏览器对 summary::marker 支持不一(Firefox 不支持自定义,Safari 默认三角),所以统一用伪元素更可靠:
真正容易被忽略的是:嵌套后 aria-controls 不会自动关联——这是无障碍硬伤,必须手写 ID 和属性,否则视障用户完全不知道哪个 summary 控制哪块内容。


















