HTML语义结构是UI架构的底层契约,决定组件复用性、无障碍支持与SEO权重;必须用<nav>等语义标签替代div+class,确保结构意图被浏览器和辅助技术准确识别。

HTML语义结构不是“加分项”,而是UI架构的底层契约——没它,样式再漂亮,组件也难复用、无障碍必挂、SEO权重会稀释。
为什么用 <nav> 代替 <div class="nav"> 不是矫情
浏览器和辅助技术(如屏幕阅读器)靠标签名识别结构意图。<nav> 自带导航语义,<div class="nav"> 只是一个空盒子。两者在视觉上可能一模一样,但前者能让键盘用户按 Tab 进入导航区后直接听到“navigation”,后者得靠额外 role="navigation" 补救,且易遗漏。
- 误用
<div class="nav">后,若团队成员改了 class 名(比如改成nav-bar),JS 钩子document.querySelector('.nav')就失效,而document.querySelector('nav')永远有效 - SEO 爬虫对
<nav>内链接赋予更高信任权重;对<div class="nav">里的链接则视为普通内容块内链接 - CSS 中写
nav ul { margin: 0; padding-left: 0; }比.nav ul { ... }更安全——不依赖 class 命名一致性,也不怕 JS 动态增删 class
<main> 必须唯一,且不能嵌套在 <section> 或 <article> 里
这是 HTML5 规范硬性要求:<main> 表示页面核心内容区域,全局只能出现一次,且必须是顶级语义容器(即直接子元素应为 <body> 的直系后代)。嵌套会导致无障碍工具误判内容层级,也会让搜索引擎困惑“哪部分才是主内容”。
- 常见错误写法:
<section><main>...</main></section>—— 这会让<main>失去“页面主干”语义,变成局部区块 - 正确做法:把
<main>放在<body>下,与<header>、<nav>、<footer>并列;内部可用多个<article>或<section>划分逻辑模块 - 如果某页有多个“主内容入口”(如仪表盘含多个数据面板),应只用一个
<main>包裹全部,再用<section aria-labelledby="panel1-title">配合标题强化可访问性
class 命名怎么配合语义标签不打架
类名不该重复表达标签已有的语义,更不该泄露布局细节。比如在 <nav> 上加 float-right,等于让 CSS 决定“导航该在哪”,破坏了结构职责分离。
立即学习“前端免费学习笔记(深入)”;
- 避免表现类名:
red-button、left-sidebar、flex-col—— 它们绑定样式特征,主题切换或布局调整时就得批量重命名 - 优先语义类名:
js-search-trigger(仅作 JS 钩子)、u-visually-hidden(工具类)、post-card--featured(修饰业务状态,非视觉) - 当需要样式变体时,用修饰符强化语义而非视觉:
card--compact不如card--summary,因为“摘要”是内容角色,“紧凑”只是渲染结果
外部 CSS 文件必须覆盖所有通用样式,<style> 块仅限极简临时场景
<style> 写在 HTML 里,意味着每次请求都得重新下载整个 HTML 文本,无法被浏览器单独缓存。哪怕只写三行样式,也拖慢首屏加载、增加带宽浪费。
- 允许用
<style>的唯一合理场景:首屏关键 CSS(如 hero banner 字体、背景色),且必须加media="print"或media="(min-width: 768px)"条件,并注释说明“critical inline CSS, sync with main.css” - 禁止在
<style>里写可复用规则(如.btn { ... }),否则其他页面复制粘贴后,改一处漏一处 - 内联样式
style="margin: 10px;"是调试陷阱——它优先级高于外部 CSS,后期想统一改边距时,得逐个找 DOM 修改,或用!important覆盖,彻底破坏层叠逻辑
真正难的不是选对标签,而是坚持不让样式逻辑反向入侵结构定义——比如为了“让卡片居中”而在 <article> 上加 class="centered",这等于用 class 名悄悄篡改了 <article> 的语义边界。



















