最轻量可靠的模块化起点是直接用header、nav、main、section、aside、footer等语义标签划分区域,无需工具或js,原生支持且利于seo与无障碍;它们不是可选装饰,而是向浏览器和辅助技术明确传达内容角色。

直接用 header、nav、main、section、aside、footer 这些语义化标签划分区域,就是最轻量、最可靠、也最容易被忽视的模块化起点。不需要构建工具,不依赖 JavaScript,浏览器原生支持,且对 SEO 和屏幕阅读器友好。
用语义标签代替 div 做功能分区
很多人写布局时习惯先套一层 div class="header",再写 div class="nav",这等于放弃了 HTML 的结构表达力。语义标签不是“可选装饰”,而是告诉浏览器和辅助技术“这部分是干什么的”。
-
header应该包裹页面或区块的标题、Logo、全局操作入口——但不要塞搜索框或用户头像下拉菜单(它们属于交互组件,更适合放在nav或独立aside) -
nav只放导航链接,不能包含非链接内容(比如“欢迎回来,张三”这类状态文本应移出nav) -
main必须且只能出现一次,且不能嵌套在article、aside或另一个main里;它代表整个页面唯一的核心内容流 -
section需有明确主题,比如“产品特性”“客户评价”;如果里面只有一段文字+一张图,考虑用article更合适 -
aside的内容必须与邻近的article或section相关,比如一篇博客旁的“延伸阅读”,而不是全站通用的广告位(后者更适合放在footer或独立section)
避免嵌套陷阱:哪些组合是错的
语义标签之间有隐含的逻辑约束,违反会导致结构混乱、无障碍失效,甚至被开发者工具标为错误。
-
main不能作为article的子元素——article是独立内容单元,main是页面级容器,二者层级冲突 -
footer不该出现在header内部——页脚不属于页眉的语义范畴,即使视觉上它紧贴在顶部下方,也应保持独立兄弟关系 -
nav里混用button或表单控件(如登录按钮)会破坏导航语义;这类交互应抽离到header或单独的section - 多个
header可以存在(比如每个article都有自己的header),但不能为了“样式统一”而把所有标题都包进一个顶层header,否则会丢失内容粒度
配合 CSS Grid/Flex 实现真正可维护的模块边界
光有语义标签还不够,得让它们在视觉和布局上真正“分得开”。这时候别靠浮动或绝对定位,优先用现代布局方式绑定语义结构。
- 给父容器设
display: grid,再用grid-template-areas显式声明区域位置,例如:"header header" "nav main" "footer footer";每个子标签加grid-area: header等对应值 - 若用 Flex 布局,确保
main和aside是同一级子元素,而非aside嵌在main里——否则语义和布局双重错位 - 对含长文本或 URL 的
section,记得加min-width: 0配合overflow: hidden,否则 Flex/Grid 默认不截断,撑破容器 - 避免给
nav或aside设固定高度;它们应随内容自然伸缩,高度控制交给父容器或媒体查询中的max-height
为什么 BEM 类名要和语义标签一起用
类名不是用来“补语义”的,而是用来扩展样式能力。比如 <article class="card"></article> 没问题,但 <div class="card"> 就丢失了内容本质。
<ul>
<li>
<code>article.card 表示“这是一个独立内容单元,同时具备卡片样式”;article.card__title 表示“这个标题属于卡片这一内容单元”
div.header + div.header__logo,而应写 header + header > .logo;前者是语义退化,后者保留结构可信度section--featured 可用于标记特殊状态,但不能改变其语义角色——section--featured 还是 section,不是 hero 或 banner
aside.sidebar,而不是新建一个叫 sidebar 的自定义标签——HTML 标准已足够表达意图最容易被忽略的点是:模块化不是把代码切碎就行,而是让每一小块都能被独立理解、测试和替换。当你删掉一段 CSS,发现 nav 里的链接顺序乱了,说明你把布局逻辑写进了样式层;当你改了一个 section 的类名,结果屏幕阅读器读不出标题层级,说明语义链断了。真正的模块化,始于标签选择,成于嵌套克制,稳于布局解耦。











