必须用<nav>包裹真实导航链接,否则搜索引擎无法识别导航意图,SEO权重和可访问性都会下降;<div class="nav">虽渲染相同,但缺乏语义,导致爬虫降权、读屏器跳过、Tab顺序混乱。

必须用 <nav> 包裹真实导航链接,否则搜索引擎无法识别导航意图,SEO 权重和可访问性都会掉档。
为什么不能用 <div class="nav"> 替代 <nav>
浏览器、读屏器、爬虫靠标签语义判断功能,<nav> 是 HTML5 明确规定的导航容器。用 <div class="nav"> 渲染效果一样,但实际后果严重:
- 搜索引擎可能把导航链接当成普通内链,不赋予“站点结构”权重
- 键盘 Tab 顺序混乱,读屏器会跳过整个区域或错误播报为“一组 div”
- 本地开发时若用
file://协议,部分 JS 路径匹配逻辑(如window.location.pathname)会失效,而语义缺失会让问题更难定位
<nav> 内部结构该用 <ul><li><a> 还是纯 <a>
必须用 <ul><li><a> 嵌套。这不是为了“好看”,而是为了两点:
- 语义完整:
<ul>表示一组并列的导航项,<li>是其中一项,<a>是可交互入口;爬虫据此推断这是“站点级导航集合” - 下拉菜单可扩展:二级菜单自然嵌套在
<li>内(<ul class="submenu">),ARIA 属性(如aria-haspopup="true"、aria-expanded)才有明确挂载位置 - 避免混入非导航元素:搜索框应放
<search>,登录按钮属于<form>或独立区域,塞进<nav>会导致读屏器播报混乱(例如:“导航,搜索框,导航,登录按钮”)
横向布局该选 flex 还是 float 或 inline-block
无条件选 display: flex。老方案在现代场景下问题集中:
立即学习“前端免费学习笔记(深入)”;
-
float: left导致父容器高度塌陷,需额外清除浮动;移动端折行后项间距错乱 -
display: inline-block因换行符/空格产生不可控间隙,font-size: 0或注释 hack 污染 HTML 结构 -
flex天然支持gap控制间距、justify-content: space-around均衡分布、flex-wrap: wrap响应式折行 - 兼容性注意:IE11 不支持
gap,此时退回到margin-right+:last-child { margin-right: 0 },但别在<nav>上写white-space: nowrap——小屏会强制横向滚动
当前页高亮必须靠 JS 动态判断,不能硬编码 class="active"
HTML 静态文件无法感知路由,硬写死 class="active" 是维护灾难:
- 路径微小差异即失效:比如
/about和/about/、带哈希的#!/projects、前端路由的动态参数 - 推荐轻量 JS 判断(放在
</body>前):
document.querySelectorAll('nav a').forEach(link => {
const currentPath = window.location.pathname || '/';
const linkPath = new URL(link.href).pathname;
if (linkPath === currentPath) {
link.classList.add('active');
}
});
注意:若用 Vue Router / React Router,必须监听路由变化事件(如 router.afterEach),不能只在页面加载时执行一次。
最容易被忽略的是面包屑和主导航的语义分离——即使都用 <nav>,也必须加 aria-label="当前位置" 区分,否则读屏器无法分辨哪段是“你在这儿”,哪段是“你能去哪”。



















