多级目录必须用原生嵌套结构,禁用div+padding模拟缩进;连线用::before/::after绝对定位绘制;交互需同时支持:hover、focus-within和active;响应式按内容密度而非固定像素断点。

多级目录必须用嵌套 ,别用 div + padding 模拟
用 <div> 加 <code>padding-left 模拟缩进,看似简单,但换字体、导出 PDF、打印或高 DPI 屏幕下极易错位。真正稳定的结构是原生 <ul></ul> 嵌套:<li> 包含文件夹名,子目录作为其直接子元素的 <ul></ul>。IE11 对 padding-left 的计算偏差会导致缩进跳变,而 margin-left + display: flex 容器能保持一致。
常见错误现象:
• 导出 PDF 时连线偏移、图标错行
• Safari 下文字缩放后缩进塌陷
• 切换等宽字体后 Unicode 图标位置漂移
- 每个层级必须用
<li>包裹,不能漏层或跨级嵌套 - 图标统一用
::before伪元素生成,禁用<img>或裸 Unicode 字符 - 缩进靠
margin-left控制,不是padding-left
连线绘制必须基于标准盒模型,禁用 transform
用 border-left + border-bottom 拼“T”形连线,在 Firefox 和 Chrome 渲染差 1px;transform: scaleY(-1) 类翻转技巧在打印时完全失效。正确做法是:垂直线用 ::before 绝对定位,固定 left: -16px、top: 0、height: 100%;横线用 ::after,只加在最后一个子 <li> 上,width: 16px、top: 50%、border-top: 1px solid #999。
关键点:
• 所有定位值用 px(非 rem/em),避免缩放干扰
• 连线高度/宽度必须与图标尺寸严格对齐
• 禁用任何 transform、scale、rotate 属性
交互状态要区分 hover / focus-within / active,不能只靠 :hover
纯 :hover 在触摸设备上无效,且键盘用户无法触发。必须同时支持:.has-submenu:hover > .submenu、.has-submenu:focus-within > .submenu、.has-submenu.active > .submenu。其中 focus-within 能捕获子项获得焦点时的父级展开,active 由 JS 添加用于移动端点击态。
容易踩的坑:
• 忘记给 <a></a> 或 <button></button> 加 tabindex="0",导致键盘无法聚焦
• 在移动端监听 click 后没手动 blur(),造成后续 focus-within 失效
• .submenu 用了 position: absolute,导致 focus-within 不触发(需设 position: static 或 relative)
响应式断点别按像素硬切,优先看内容撑不撑得住
设 @media (max-width: 768px) 并不能解决实际问题——有些 768px 平板横屏下菜单文字已挤成两行,而某些 1366px 笔记本因 DPI 高反而显示模糊。真正该监测的是内容密度:当目录项文字超过 85 字符、或缩进层级 > 4 时,就该切换为折叠模式。
建议写法:
• 用 em 断点:@media (min-width: 48em)(适配用户自定义字号)
• 移动优先,基础样式默认展开,大屏才加 min-width 增强
• 折叠逻辑用 JS 检测 offsetWidth 与 scrollWidth 差值,比媒体查询更精准
最易被忽略的一点:所有缩进、连线、图标尺寸必须在断点切换时同步重算,不能只改 display。否则小屏下仍保留 4 级缩进的 margin-left,会把内容推出视口。











