BEM 的本质是通过 block__element--modifier 命名结构划清样式归属边界,而非单纯加长 class 名;它模拟组件封装,确保样式仅作用于特定 UI 单元,避免全局污染与冲突。
为什么
名一长就失控?BEM 不是起名规则,是作用域切分
CSS 没有天然的作用域,
在哪都能生效,哪怕它本该只属于某个弹窗里的操作区。BEM 的核心不是让名字变长,而是用命名结构强行划出「这个样式只归这个组件管」的边界。
这套写法本质是在模拟组件封装——
一眼能看出它属于
块,是
元素,处于
状态,跟其他
完全无关。
常见错误现象:
被全局 reset 影响、第三方 UI 库的
覆盖了自己写的、改一个按钮样式结果所有
都变了。
不要把 BEM 当成“加前缀”,而要当成“声明归属”:每个
必须能反向定位到唯一组件文件或区块
名必须对应真实可复用的 UI 单元(如
、
),不能是语义化泛称(如
、
)
嵌套层级超过
就该拆组件,BEM 不支持三层以上元素嵌套
怎么避免
和
写错位置?用工具链卡死语法
BEM 手写容易错:把
写成
,浏览器不报错,但预处理器或 CSS-in-JS 工具可能无法识别修饰符,导致样式失效或热重载异常。
使用场景:团队协作、老项目渐进式改造、CI/CD 流水线中做样式合规检查。
立即学习
“
前端免费学习笔记(深入)
”;
在 ESLint 中接入
插件,强制校验
命名格式
Vite / Webpack 构建时加
,自动将
编译为
,减少手误
VS Code 安装
插件,输入
自动补全元素,
补全修饰符
和
混用时,BEM 还有效吗?
在 CSS Modules 或 Vue
中,
会逃逸作用域,破坏 BEM 的隔离性。一旦用了
,这个类就又变成全局污染源。
使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
下载
性能影响:CSS Modules 本可对
类做哈希混淆(如
),但
类保留原名,压缩率低,且无法 Tree-shaking。
只在必须对接外部库(如第三方富文本编辑器输出的 HTML)时才用
,且限定在最小选择器粒度,例如
,而非
React 中优先用
动态拼接
类,而不是退回到全局
Vue SFC 中避免
和
混用,二者作用域模型冲突
伪类和响应式断点怎么塞进 BEM?别硬塞,用修饰符接管
有人写
或
,这会让 BEM 边界失效——hover 是状态,不是组件自身的一部分;媒体查询是环境条件,不该由组件内部决定布局逻辑。
正确做法是把状态和环境映射为修饰符,在 JS 层控制类名切换。
交互状态统一走
、
、
修饰符,由事件监听器添加/移除,而不是靠伪类
响应式行为交给父容器修饰符驱动,例如
控制图片尺寸,组件自身不写媒体查询
动画用
修饰符 + CSS transition,避免在
里写
导致状态不可控
最易被忽略的一点:BEM 的边界感不在命名长度,而在「谁有权增删这个 class」。如果设计师给的标注稿里写的是
,而你硬改成
,却没同步更新所有调用方的 JS 逻辑,那再规范的命名也白搭。
class.btnblock__element--modifiermodal__close-btn--disabledmodalclose-btndisabledbtn.btn.btn.btnclassblockheaderproduct-cardsectioncontainerblock__element__subelement__--menu__item--activemenu--item__activestylelint-selector-bem-patternclasspostcss-bem&__content.card__contentBEM Tools.card__.card--:global():local():global(.modal__overlay):globallocalmodal__overlay_abc123:global:global:global(.ql-editor p):global(.ql-editor)clsxlocalclass.button:hover@media (min-width: 768px) { .button__text { ... } }--hover--focus--pressedlayout--tablet .card__image--animating:hovertransition.btn-primaryform__submit-btn--primary