多级目录在移动端必须采用语义化嵌套结构,即父<li>内嵌<ul class="submenu">且紧随触发元素后,配合<nav>容器、role属性、checkbox驱动显隐、≥48×48px触控目标、≤6层DOM深度、面包屑嵌入<nav>内并用<ol>与aria-current="page"、弹层需inert/aria-modal/focus管理,以及aria-expanded严格同步状态。

多级目录在移动端必须用语义化嵌套结构
直接写 <ul><li>一级</li><li>二级</li></ul> 是撑不起多级交互的。浏览器和屏幕阅读器根本识别不出“二级”是“一级”的子项,JS 也无从绑定展开逻辑。
- 正确结构必须是父
<li>内嵌<ul class="submenu">,且子<ul>紧跟在父<a>或触发元素之后,不能隔开标签或用<div>包裹 -
<nav>是必需容器,不能用<div class="nav">替代——否则 TalkBack 不会把整块区域识别为导航流,焦点跳转会断裂 - 每层
<ul>必须有明确 role 属性:role="menu"(顶层)和role="menuitem"(每个<li>),但仅当 JS 控制时才需加;纯 CSS 实现可省略,靠原生语义就够了
纯 CSS 实现展开收起时的层级限制与触控安全区
用 :hover 或 :focus-within 控制显示,看似简洁,但在移动端实际不可靠:iOS Safari 不触发 :hover,Android 多数 WebView 对 :focus-within 支持不一致,且没有“悬停”概念。
- 必须改用
input[type="checkbox"] + label + ul模式,用 checkbox 的 checked 状态驱动ul显隐,这是目前唯一稳定、无需 JS、兼容 VoiceOver 的方案 - 每个可展开项的触控目标(即
label或input)必须满足 ≥48×48px,不能只靠文字 padding 勉强达标;建议设min-height: 48px并用display: flex; align-items: center垂直居中 - 相邻可展开项间距至少 8px,否则手指滑动切换焦点时容易误触两个,尤其在窄屏上
- DOM 深度务必 ≤6 层:例如
<nav><ul><li><label><input></label><ul><li>…</li></ul></li></ul></nav>已达 5 层,再套一层<div>就超限
面包屑式导航在多级目录中的 DOM 位置陷阱
很多人把面包屑写在页面顶部、独立于导航结构之外,结果导致两个问题:一是屏幕阅读器无法建立“当前路径”与“可操作菜单项”的语义关联;二是 JS 动态更新路径时,焦点流中断,用户不知道自己点进哪一层了。
- 面包屑必须作为导航结构的一部分,放在
<nav>内部、主菜单上方,且用<ol class="breadcrumb">而非<div>——<ol>的语义天然表达顺序路径 - 每一级
<li>中的链接,若对应当前激活层级,必须加aria-current="page",否则 TalkBack 只读“链接”,不说明“这是当前位置” - 面包屑里的文字不能只是静态文本,必须是真实可点击的
<a>,哪怕当前页就是它自己——否则键盘用户无法用 Tab 回退到上一级
弹层式多级选择在真机上的 focus 管理难点
用 dialog 或 position: fixed 弹出子菜单,视觉清爽,但极易破坏焦点管理:弹层打开后,背景内容仍可被 VoiceOver 扫描到,用户滑动可能跳进不该出现的区域;关闭后焦点又常丢失回原触发点。
立即学习“前端免费学习笔记(深入)”;
- 弹层打开时,必须用
inert属性(或手动设aria-hidden="true"+tabindex="-1")冻结背景区域,否则 iOS VoiceOver 会继续遍历 - 弹层自身要设
role="dialog"和aria-modal="true",并确保首次聚焦落在第一个可操作元素(如首项<button>) - 关闭弹层后,必须显式调用
triggerElement.focus(),不能依赖浏览器自动恢复——Safari 在 modal 关闭后常把焦点丢到<body> - 避免用
transform: scale()或opacity控制显隐:它们不阻断焦点流,用户仍能 Tab 进去;必须配合display: none或visibility: hidden
aria-expanded 必须与真实状态严格同步**。JS 切换时漏掉这句,或者纯 CSS 方案里忘了用 [checked] ~ ul 配合 aria-expanded="true",都会让屏幕阅读器读错“已展开/已折叠”,用户完全无法判断当前层级是否可点。



















