必须用<nav>包裹导航结构,因为它是HTML5明确规定的语义化导航容器;用<div class="nav">虽渲染相同,但会导致搜索引擎降权、读屏器跳过、Tab顺序混乱,且无法准确识别站点结构。

为什么必须用 <nav> 包裹导航结构
不用 <nav> 也能显示链接,但浏览器和读屏器就认不出“这是导航”——SEO 权重降低,键盘用户无法快速跳转,视障用户得逐行听完整页才能找到菜单。这不是“锦上添花”,是基础语义底线。
常见错误现象:<div class="nav"> 里塞了搜索框、登录按钮、广告横幅;或者整个页面只有一层 <nav>,却把侧边分类、页脚快捷入口全塞进去。
- 每个独立导航区域(顶部主菜单 / 侧边栏 / 页脚链接)都该单独套一层
<nav>,别嵌套 -
<nav>内部必须是语义化列表,推荐<ul><li><a>,哪怕只有单个链接也这么写 - 禁用
<nav>里混入非导航内容:搜索框用<form>或<header>,登录按钮归到<aside>或独立区块
display: flex 布局下怎么让导航项均匀撑开又不换行错位
老办法用 float 或 inline-block 容易塌陷、有空白间隙、响应式时一加 media query 就错位。flex 是现代起点,但光写 display: flex 不够,关键在子项控制。
常见错误现象:5 个菜单项在小屏下挤成一团;“首页”和“关于我们”文字长度差异大,间距看着不匀;加了 flex-wrap: wrap 后换行后第二行项左对齐,不是居中。
立即学习“前端免费学习笔记(深入)”;
- 父容器设
display: flex+justify-content: space-between—— 对菜单项数量变化鲁棒性最强,2 项自动撑满,5 项也不挤 - 若文字长度差异明显,改用
justify-content: space-around更均衡 - 必须加
flex-wrap: wrap防止溢出,而不是等它错位了再靠 JS 控制显隐 - 移动端折叠前,先确保所有
<a>的点击热区 ≥ 44×44px,别只靠 padding 撑,用min-width或line-height辅助
静态页面如何实现“当前页高亮”,且不依赖 JS
很多人试图用 JS 监听 URL 动态加 class="active",结果页面一刷新就失效,或 SPA 路由没配好直接白屏。其实纯静态场景下,高亮就是手动活——每个页面自己决定哪个链接该亮。
常见错误现象:写了 a.active { color: #007bff; },但页面里没任何一个 <a> 带 class="active";或者用了 href="#" 占位,导致点击没跳转还触发页面滚动。
- 每个页面的 HTML 源码里,对应当前页的
<a href="/about.html">必须手动加上class="active" - 同时补
aria-current="page",这是给读屏器用的标准属性,比 class 更可靠 -
href值必须真实可达:本地开发用./about.html,部署在子路径用相对路径,托管在根域用/about.html - 别用
<div>或<span>冒充可点击元素——只有<a>才有原生 focus、keyboard 导航和默认手型光标
移动端汉堡菜单的 ARIA 属性怎么配才不出错
光写个图标+隐藏 <ul> 不算完成。键盘用户按 Tab 进不去,读屏器朗读不到子菜单,甚至点开后按 Esc 关不掉——全是 ARIA 配错或漏掉的后果。
常见错误现象:汉堡按钮写了 aria-controls="menu",但目标 <ul id="Menu"> 的 id 大小写不一致;子菜单始终 aria-hidden="true" 硬编码,展开后读屏器仍跳过;没加 aria-haspopup="true",辅助工具无法识别这是下拉触发器。
- 汉堡按钮的
aria-controls值必须严格等于目标菜单容器的id,大小写、连字符、空格一个都不能差 - 子菜单容器用
<div role="menu">包裹,每个子项用<button role="menuitem">,别用<a> - JS 控制显隐时,同步切换
aria-expanded(按钮)和aria-hidden(菜单),不能静态写死 - 必须支持 Enter/Space 触发展开、Esc 关闭、ArrowDown 进入第一个子项——这些不是“增强体验”,是 WCAG 强制要求
<nav>、aria-current、aria-controls 这些标签和属性,不渲染像素,但决定了谁能在页面里真正“被看见”。



















