替代
因为浏览器和读屏器只认<nav><ul><li><a></a></li></ul></nav>这条语义链——<nav></nav>告诉辅助技术“这是主导航区”,<ul></ul>表示逻辑并列项,<li>是可聚焦的独立导航单元。如果中间插个<div>,键盘 Tab 顺序会跳过整个菜单,SEO 权重也会被降级。
<p>常见错误现象:<code><nav><div class="menu"><div><a>首页</a></div></div></nav>——这种结构在 VoiceOver 或 NVDA 下根本读不出“共 4 个菜单项”,且 CSS 的 :hover 和 :focus-within 在子菜单上会失效。
-
<nav></nav>内部只放真正用于跳转的链接,logo、搜索框、用户头像这些非导航内容不要塞进去
- 多个侧边栏(比如后台管理菜单 + 快捷工具栏)要各自独立用
<nav></nav>,并加aria-label区分,例如<nav aria-label="系统设置菜单"></nav>
- 如果侧边栏只是推荐文章或广告位,改用
<aside></aside>更合适,<nav></nav>只留给有明确导航意图的结构
侧边栏如何用Flexbox控制流向而不依赖JavaScript
Flexbox 是让侧边栏在桌面端垂直排列、移动端横向收起的核心,不用 JS 就能响应式切换布局方向。关键不是写flex-direction: column,而是配合媒体查询切断默认文档流。
常见错误现象:写了@media (max-width: 768px) { .sidebar { flex-direction: row; } },结果小屏下菜单挤成一行还溢出屏幕——这是因为没重置width、overflow和flex-shrink。
- 桌面端默认设
display: flex + flex-direction: column,用gap: 0.75rem控制项间距(比margin更可靠)
- 移动端断点内必须加
width: 100% + overflow: hidden,否则 Flex 容器会撑宽父级
- 每个
<li>里<a></a>要设display: block,不然点击热区只有文字部分,触控体验差
- 别用
float或inline-block模拟垂直菜单——它们无法响应flex-wrap或align-items,且在 Safari 中容易错位
下拉子菜单怎么嵌套才不崩定位和焦点
子菜单必须作为对应<li>的直接子元素,即<li><ul><li><a></a></li></ul></li>。任何平级或外置写法都会导致 CSS 定位偏移、键盘焦点丢失、读屏器播报中断。
html-deploy
使用 htmlcode.fun 将 HTML 内容或文件部署到网页,适用于用户要求“部署到网页”“托管此 HTML”“生成此前端...的实时链接”等场景。
下载
常见错误现象:子菜单写在<nav></nav>末尾,靠position: absolute + top: 100%硬拉上去——这样移动端展开后经常飘到屏幕外,且 Tab 键无法进入子项。
- 子菜单
<ul></ul>初始状态用position: absolute + left: 100%(右侧展开),避免遮挡父菜单
- 触发显示时,用
:has(> ul)或 checkbox + :checked ~控制显隐,不要依赖 JS 的classList.toggle()
- 每个子菜单项
<a></a>必须设display: block,否则 iOS Safari 点击区域小于 44×44px,触发失败率高
- 展开后立即把焦点移到第一个子项:
document.querySelector('ul.submenu a').focus(),否则键盘用户得按十几次 Tab 才能进去
移动端汉堡按钮怎么避免点击穿透和滚动卡顿
点击汉堡图标后,手指抬起却触发了下方链接,或者侧边栏展开时页面无法滚动——这通常是因为pointer-events没关、transform没启用硬件加速、或inert属性缺失。
常见错误现象:用display: none隐藏侧边栏,再用 JS 切换display: block——这样会导致 DOM 重排,动画卡顿,且屏幕阅读器无法感知状态变化。
- 用
transform: translateX(-100%) + transition: transform 0.3s ease实现滑入,比left或margin更顺滑
- 展开时给
加inert属性(现代浏览器支持),或手动设pointer-events: none防止穿透
- 侧边栏容器加
scroll-behavior: smooth,避免滚动突然跳变;主内容区加overscroll-behavior: contain防回弹
- 汉堡按钮本身必须设
width: 44px + height: 44px,iOS 和 Android 最小触控尺寸标准,别靠padding凑
侧边栏最易被忽略的点不在结构或动画,而在状态同步:JS 控制展开时,必须同步更新
aria-expanded、
inert、焦点位置三者,缺一不可。否则键盘用户和读屏器看到的永远是“已关闭”状态,哪怕菜单已经滑出来了。