HTML语义化是SPA结构稳定与可维护的基础;main须唯一且不嵌套,nav/header需区分全局与局部,aside仅用于弱耦合内容,CSS模块化须与语义对齐,避免样式污染与协作卡点。

大规模单页应用(SPA)不是把所有 HTML 塞进一个 index.html 就完事——结构失控、样式污染、协作卡点,往往从第一行 div 开始。
HTML 结构必须语义化,否则 Flex/Grid 白配
很多人给 body 加了 display: flex 和 min-height: 100vh,但子元素还是撑不开,根本原因是没用对语义标签。浏览器和辅助工具靠 header、main、aside 理解页面逻辑,不是靠 class 名猜。
-
main必须唯一,不能嵌套在section或article里;它只包裹主内容流,不是“主要内容区”的视觉占位符 -
aside适合侧边推荐、相关链接这类可独立存在、与当前上下文弱耦合的内容;别把它当“右边那栏”硬套 - 避免
<div class="header">这种写法——既没语义,又让 JS 查找document.querySelector('header')失效 - Flex 主轴控制必须落在语义容器上:比如
body { display: flex; flex-direction: column; },再给main设flex: 1,而不是在一堆div上堆flex
CSS 模块化协作,靠命名约束,不靠 !important
多人协作时样式打架,90% 源于 class 名随意、选择器过深、ID 选择器滥用。BEM 不是教条,是降低理解成本的最小公约数。
- 公共样式抽到
base.css,用g-前缀(如g-mt-16),禁止在其中写body > .m-card这类强耦合规则 - 模块样式统一用
m-前缀(如m-product-list),每个模块的 CSS 文件只管自己,不越界影响其他区域 - 禁用 ID 选择器写样式:
#user-profile看似唯一,但 JS 也用它做getElementById,改样式可能意外打断交互逻辑 -
<style>标签只用于极简 demo;真实项目中,所有样式必须走外部<link rel="stylesheet">
路由切换时 DOM 重用与清理,比渲染更关键
SPA 页面跳转不刷新,但旧组件的事件监听、定时器、fetch 中断没清理,内存泄漏和点击错乱就来了。React/Vue 自动处理这些,纯 HTML + JS 手动实现时容易忽略。
立即学习“前端免费学习笔记(深入)”;
- 每次路由切换前,先调用旧模块的
destroy()方法(如果提供),移除addEventListener、清除setTimeout/setInterval - 动态插入内容时,别直接拼接字符串赋值给
innerHTML;优先用document.createElement+textContent防 XSS,或用模板字符串配合insertAdjacentHTML('beforeend', ...) - 用
History.pushState()切换 URL 后,必须手动触发视图更新;监听popstate时注意首次加载无该事件,需额外判断location.pathname - 长列表滚动锚点、表单输入焦点等状态,不能依赖 DOM 存活——要显式保存到
sessionStorage或模块内部 state
静态资源路径与 HTML 拆分,不是“能跑就行”的事
大型 SPA 表面是单个 index.html,但实际构建产物里,JS/CSS/图片都按模块拆包。HTML 本身若不提前规划结构,后续加 CDN、换主题、做暗色模式,全是硬编码改路径。
- 所有页面共用的
<head>内容(<meta name="viewport">、<link rel="stylesheet">)必须抽成模板片段,用构建工具(如 Eleventy)或 JS 动态加载,不能每个 HTML 文件里复制粘贴 - 图片路径统一用相对路径,根目录起始(如
/assets/icons/logo.svg),避免../images/嵌套过深导致路径错乱 - 构建后产出的 HTML 要支持环境变量注入:比如
data-api-base="/api/v2",而不是把接口地址硬写死在 JS 里 - 如果用 Webpack/Vite,HTML 插件(如
html-webpack-plugin)应配置template和inject: 'body',确保 script 标签自动插入到底部且顺序可控
真正难的不是写出能跑的单页,而是让不同人改不同模块时,不会因为一个 flex: 1 或一个 .btn class 影响到三屏之外的布局——语义结构、CSS 作用域、DOM 生命周期、资源路径,四者缺一不可。



















