必须用 ul/li 嵌套结构实现多级折叠菜单,子 ul 必须是父 li 的直接子元素,配合 aria-haspopup、aria-expanded、role="menubar"/"menu"/"menuitem" 及 input[type="checkbox"]+label+~.submenu 纯 css 方案,确保可访问性与跨端兼容。

别用 details 嵌套实现多级折叠菜单——它不被 HTML5 规范支持,iOS Safari 和微信 X5 内核会直接失效,状态不同步是必然结果。
必须用 ul/li 嵌套结构,子 ul 是父 li 的直接子元素
浏览器和屏幕阅读器只通过 DOM 树层级识别父子关系。任何偏离这个结构的写法,都会导致键盘导航跳过、aria-expanded 同步失败、CSS 选择器匹配错层。
- ✅ 正确:
<li> <a>Products</a><ul><li><a>Laptops</a></li></ul> </li> - ❌ 错误:
<li><a>Products</a></li> <ul><li><a>Laptops</a></li></ul>(子ul在父li外) - ❌ 错误:
<li> <div><a>Products</a></div> <ul><li><a>Laptops</a></li></ul> </li>(div插入破坏li直接包含ul的关系) - 所有可展开项必须加
aria-haspopup="true"和初始aria-expanded="false",否则屏幕阅读器无法识别交互意图
input[type="checkbox"] + label + ~ 是最稳的纯 CSS 折叠方案
相比 :hover(手机上无效)或 details(嵌套不可靠),这个组合能记住展开状态、兼容触摸设备、无需 JS 就能保持语义完整。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
-
<input type="checkbox" id="menu-1">必须紧邻<label for="menu-1"></label>,中间不能有换行、空格或其它标签(HTML 空白符会被解析为文本节点,破坏~兄弟选择器) -
<ul class="submenu"></ul>必须紧跟在label后面,且是它的**直接兄弟节点** - CSS 规则必须写成:
input[type="checkbox"]:checked ~ .submenu { display: block; },不能用visibility或opacity,否则焦点仍可达但视觉不可见,违反可访问性 - 缩进统一用
padding-left+border-left,避免margin-left导致 tab 键聚焦框偏移
移动端必须强制收起所有子菜单,不能靠 @media 仅隐藏
小屏下若允许多级同时展开,内容区会被严重挤压,甚至触发横向滚动——这不是体验问题,而是布局失控。
- 用
@media (max-width: 768px)重置所有.submenu为display: none,且不依赖 JS 切换 - 确保顶级
ul上有role="menubar",每层ul加role="menu",每个a加role="menuitem" - 如果需要点击展开,JS 只负责切换
class="is-open",CSS 控制显隐,不要操作style.display直接赋值(会覆盖媒体查询) - 微信内嵌浏览器(X5 内核)对
details标签支持极差,检测到MicromessengerUA 时,应直接渲染div+button降级结构,并补全aria-expanded和tabindex="0"
真正难的不是写几层 ul,而是让每一层的 DOM 位置、CSS 选择器作用域、ARIA 属性更新节奏完全对齐——漏掉一个 role,键盘用户就卡在第二层;少一个 ~,整个折叠逻辑就失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










