语义化标签是dom结构的硬约束,而非锦上添花:原生标签(如、、)自动进入无障碍树,使屏幕阅读器、搜索引擎可理解结构;用替代将主动放弃该能力,导致seo下降、lighthouse评分低、js类名绑定脆弱等问题。

语义化标签不是“锦上添花”,而是DOM结构的硬约束
浏览器解析HTML时,会同步构建两棵树:渲染树和无障碍树。只有原生语义标签(如 <header></header>、<nav></nav>、<main></main>、<section></section>、<footer></footer>)才能自动进入无障碍树——这意味着屏幕阅读器、搜索引擎、自动化测试工具能真正“理解”你的结构。用 <div class="nav"> 替代 <code><nav></nav>,等于主动放弃这部分能力。
常见错误现象包括:SEO收录率低、Lighthouse可访问性评分卡在60分以下、JS通过 document.querySelector(".header") 绑定事件后,改个类名就全崩。
- 所有页面级容器必须用语义标签,禁止出现连续三层以上
<div> 嵌套 <li> <code><main></main>全局唯一,且不能作为<article></article>或<section></section>的直接父级 -
<time datetime="2026-07-02"></time>这类带机器可读属性的标签,必须补全datetime值,否则等同于没写 - 检查 Elements 面板里的**实际渲染DOM**,不是源码缩进——JS动态插入或模板引擎拼接后可能更糟
-
<iframe></iframe>、<img>等替换元素自带隐式盒模型,别再在外层加<div class="wrapper"> <h3>Vite + HTML Modules 是当前最轻量的工程化落地路径</h3> <p>毕业设计或中小项目没必要上Webpack或React。Vite 启动快、热更新准、原生支持 <code>import语法,配合浏览器原生模块能力,就能实现真正的组件复用——比如导航栏抽成nav.html,用fetch()加载后insertAdjacentHTML注入,比复制粘贴10次安全得多。但要注意:Vite 默认不处理纯HTML文件的模块导入,需手动配置
vite-plugin-html或用<script type="module"></script>加载逻辑。- 所有公共片段(页头、页脚、侧边栏)统一放在
/src/partials/目录,命名与文件名严格一致 - 避免在HTML里写内联脚本;JS逻辑统一用
type="module"引入,利用ESM的静态分析优势 - 图片、字体等资源路径全部走
./assets/,Vite会自动哈希并注入正确路径,不用手写../..
class命名不是风格偏好,而是协作契约
当多人维护一个项目时,
class="red-text"和class="btn-primary"的区别在于:前者描述样式,后者描述意图。一旦设计系统换色,前者要全局搜索替换,后者只需改CSS变量。更隐蔽的问题是命名冲突:
.container在Bootstrap里是固定宽度居中,在你自己写的轮播组件里却是相对定位容器——两个CSS文件一合并,样式就打架。- 强制使用 kebab-case(小写+短横线),如
user-profile-card,禁用下划线或驼峰 - 禁止用纯样式词(
left、big、red),改用功能/内容词(sidebar-nav、hero-cta) - 布尔状态统一用双连字符修饰符:
is-loading、has-error,而不是loading或error
<div> 前是否真问过自己:这个节点有没有语义?它会不会被JS或CSS强依赖?它在无障碍树里存在吗?</div> - 所有公共片段(页头、页脚、侧边栏)统一放在
嵌套深度超过4层时,首屏性能已开始受损
实测表明:DOM节点嵌套达5层时,在中低端安卓设备上可导致首屏延迟20–50ms。这不是理论值,而是真实用户可感知的卡顿。问题不在于你写了多少JS,而在于浏览器构建DOM树时多做了几次节点创建和样式计算。
容易踩的坑是把BEM类名逻辑直接映射到DOM结构——比如看到 card__content--large 就本能套一层 <div class="card__content">,结果 <code><div><div><div>
<p> 一气呵成。</p>
<ul>
<li>优先用 <code>display: contents 或 Flex/Grid 容器直排子元素,跳过无意义包裹层











