BEM规范要求Grid子元素类名必须带完整块名路径、禁止三层嵌套、禁用后代选择器;grid-area值须与class名严格一致;布局撑满由Grid轨道控制,非元素自身伸缩;响应式不改类名只调grid-template-areas;类名本质是语义锚点而非格式装饰。

Grid 容器本身就是一个 Block,它的子元素类名必须带完整 BEM 路径,不能省略块名、不能嵌套三层、不能靠后代选择器“猜”归属。
grid-area 值必须和 class 名严格一致
CSS 里写 grid-area: email-field,HTML 就必须写 <div class="login-form__email-field">。不一致会导致调试时搜不到对应样式,JS 查询也拿不到上下文。
<ul>
<li>常见错误:<code>grid-area: header + <header class="header"></header>(孤立类名,脱离 Block)
login-form__email-field、login-form__submit-btn
.login-form .email-field 这类后代选择器——BEM 不靠 DOM 层级定位,靠类名锚点禁止三层及更深的 __ 嵌套
BEM 明确不允许 login-form__fields__phone-verify-group 或 dashboard-grid__main-content__card-grid 这类写法。它不是“语法报错”,而是语义崩塌:你已无法回答“这个东西到底属于谁、能不能单独复用”。
- 当一个区域具备独立状态(如加载中、校验失败)、可复用逻辑(增删字段)、或需单独测试时,它就该是 Block,不是 Element
- 正确升格:
phone-verify-group、card-grid,内部用phone-verify-group__input、card-grid__item - HTML 中只需在父 Block 下放一个
<div class="phone-verify-group">,不掺杂父级前缀 <h3>每个 <code>__元素只负责视觉边界,不接管布局撑满dashboard-grid__header是一个有明确边界的视觉模块,不是“占位符”。用grid-column: 1 / -1强行拉宽,会破坏它的盒模型完整性,后续加border、box-shadow或padding时极易错位。立即学习“前端免费学习笔记(深入)”;
- 布局撑满应由 Grid 轨道定义控制(
grid-template-columns、grid-template-areas),而非靠元素自身伸缩 -
dashboard-grid__header的 CSS 规则里只写语义相关样式:背景色、内边距、字体大小等,不写width、grid-column - 如果某元素需要横跨多列但又不想破坏边界,优先考虑用
grid-area指向一个新命名的区域,而不是硬撑
响应式不改类名,只动
grid-template-areas移动端把
sidebar挪到main下面,class还是dashboard-grid__sidebar。名字描述的是角色,不是位置。改类名等于放弃语义锚点,搜索、重构、协作全受影响。- 媒体查询里只重写
grid-template-areas字符串,比如从"header header" "sidebar main"改成"header" "main" "sidebar" - 需要状态变化(如抽屉展开)用修饰符:
dashboard-grid__sidebar--drawer,不是dashboard-grid__sidebar-mobile - 所有类名保持稳定,才能让
grep dashboard-grid__真正查出全部关联代码
最常被忽略的一点:BEM 类名不是为了“看起来规范”,而是为了让人在不打开 CSS 文件的情况下,仅凭 HTML 就能判断这个节点的职责边界、复用可能性、以及是否该为它单独写测试用例。一旦开始用
__命名却放任它承载多层逻辑,规范就退化成了字符累加器。 - 布局撑满应由 Grid 轨道定义控制(


















