【转】《从WEUI看BEM的强大:组件化开发的命名艺术》
原文:https://juejin.cn/post/7509498122202382351?utm_source=gold_browser_extension
《从WEUI看BEM的强大:组件化开发的命名艺术》
📖前言
打开微信的组件库WEUI,查看源码,你会发现,它的CSS的各个组件似乎在命名上遵循着一种规范,让我们能够清晰地了解各个组件是什么。这些规范就是我们今天要介绍的主角--BEM命名规范
实际上,BEM在大型项目、复杂前端架构中非常流行,其实就有知名的Google、GitHub、Yandex等等公司和项目在广泛使用。
那么BEM到底具体是怎么用的,以及它到底神奇在哪呢?让我为你详细介绍!
图:WEUI的部分CSS源码
🧩BEM核心概念
BEM 是一种前端 CSS 命名规范,旨在提高代码的可读性、可维护性和可扩展性,BEM的核心组成是块(Block)、元素(Element)、修饰符(Modifier)三部分。
块(Block)
块是指独立的功能模块(如导航、表单、按钮),是页面的基本组成单元
块的命名规则是:项目代号 -
区块的作用或职责,用短横线-
连接
实例:weui-page
(微信的页面块)、weui-btn
(微信的按钮块)
块的特性
样式隔离:
通过weui
作为项目代号,可以避免与其他库冲突(如Bootstrap)。
块的可复用性:
当我们按上述命名规则实现块了之后,我们会发现只要定义好某一个块的CSS样式,很多地方都可以使用这个块,共享CSS样式了。
块的封装性:
我们通过weui-page
包裹着里面的各式各样的元素,其内部样式设置由块自身控制,外部无需干预,例如下面代码:
css 体验AI代码助手 代码解读复制代码.weui-dialog {
padding: 20px; /* 控制弹窗内部整体间距 */
}
块 .weui-dialog
的 padding
会影响其所有内部元素(__hd
、__bd
),但不会泄漏到外部,外部无需知道块的内部实现细节,只需使用块即可。
元素(Element)
元素是块的组成部分,不能独立存在(如按钮的图标,菜单的选项)
命名规范:元素用 块名__
元素名 来实现,用双下划线__
连接。
实例:weui-page__title
(页面块中的标题),weui-btn__icon
(按钮块中的图标)
元素的特性
从属于块:
元素必须属于某个块,不能独立存在,比如dialog__hd
这种就不符合BEM规范,元素没有在块中,这样做的目的是为了确保样式作用域清晰,避免全局污染的问题
BEM的扁平结构原则:
元素(Element) 直接属于 块(Block) 或 子块(Sub-block) ,而不是其他元素。
错误代码:
html 体验AI代码助手 代码解读复制代码<!-- 违反BEM原则 -->
<div class="menu">
<ul class="menu__list">
<li class="menu__list__item">...</li> <!-- 错误:元素嵌套元素 -->
</ul>
</div>
BEM原则是:元素应是块的直接子级,尽量避免元素嵌套其它元素。 以下是推荐写法
html 体验AI代码助手 代码解读复制代码<div class="menu">
<ul class="menu__list">
<li class="menu__item">...</li> <!-- 直接属于menu块 -->
</ul>
</div>
修饰符 (Modifier)
修饰符用于定义块或元素的不同状态、样式或变体,提供灵活的可扩展性。
命名规则:描述符的命名规则是块/元素名 + 双连字符 + 修饰符名:block--modifier
或 block__element--modifier
,使用双横杠--
连接。
案例:weui-tabbar__item--active
(激活状态)、weui-btn--loading
(加载中的按钮)
修饰符特性
可组合性
实际上,一个块或者元素可以同时有多个修饰符。 比如.weui-btn--primary.weui-btn--disabled
语义化命名
使用修饰符时,需要注意见名知义,特别是在团队合作写UI组件时,你的同事,看到你的修饰符的名字,就能够了解该块或者元素的状态,能够更好地协作开发!
🛠️BEM的综合实战
下面给出一段代码,详细,准确应用了BEM命名规范,大家可以进行参考
【遵循BEM的综合应用】(点击展开)
html 体验AI代码助手 代码解读复制代码 <body>
<!--
1. 整个页面是一个大模块(Block),类名"weui-page"表示"微信UI-页面"
BEM规范:Block是独立且有意义的组件
-->
<div class="weui-page">
<!--
2. 页面头部区域(Element),属于weui-page的一部分
BEM规范:Element用双下划线__连接,表示属于某个Block
-->
<header class="weui-page__header">
<!-- 3. 页面标题(Element) -->
<h1 class="weui-page__title">Button</h1>
<!-- 4. 页面描述(Element),desc是description的缩写 -->
<p class="weui-page__desc">按钮</p>
</header>
<!-- 5. 页面主体内容区域(Element) -->
<main class="weui-page__body">
<!--
6. 按钮区域(新的Block),可以独立存在和复用
BEM规范:新的功能区块应该作为新的Block
-->
<div class="weui-button-area">
<!--
7. 主要按钮(Block + Modifier)
BEM规范:Modifier用双横杠--连接,表示状态或变体
-->
<a href="#" class="weui-btn weui-btn--primary">主要操作</a>
<!-- 8. 默认按钮(Block + 不同Modifier) -->
<a href="#" class="weui-btn weui-btn--default">次要操作</a>
</div>
<!-- 9. 单元格列表(新的Block) -->
<div class="weui-cells">
<!-- 10. 列表标题(Element) -->
<h3 class="weui-cells__title">个人信息</h3>
<!-- 11. 单个单元格(Block) -->
<div class="weui-cell">
<!-- 12. 单元格头部(Element) -->
<div class="weui-cell__hd">
<!-- 13. 单元格图片(Element) -->
<img src="" alt="" class="weui-cell__img">
</div>
<!-- 14. 单元格主体内容(Element) -->
<div class="weui-cell__bd">
<!-- 15. 单元格文本(Element) -->
<p class="weui-cell__text">标题文字</p>
</div>
<!-- 16. 单元格尾部(Element) -->
<div class="weui-cell__ft">
<!-- 17. 单元格描述文字(Element) -->
<span class="weui-cell__desc">说明文字</span>
</div>
</div>
</div>
<!-- 18. 表单区域(新的Block) -->
<div class="weui-form">
<!-- 19. 表单头部(Element) -->
<div class="weui-form__hd"></div>
<!-- 20. 表单主体(Element) -->
<div class="weui-form__bd"></div>
<!-- 21. 表单尾部(Element) -->
<div class="weui-form__ft"></div>
</div>
</main>
</div>
</body>
🚀BEM的应用
在前面,我们已经掌握了BEM的核心概念以及命名规范 不仅是一种 CSS 命名规范,更是一种前端架构思维,适用于各种复杂项目。以下是 BEM 在实际开发中的典型应用场景和最佳实践。
- 组件化开发(React/Vue/Angular)
BEM 天然适合组件化开发,每个组件对应一个 Block,内部元素使用 Element,不同状态用 Modifier。
- 大型项目(团队协作)
BEM 的严格命名规则能有效避免样式冲突,适合多人协作开发。
- UI 库设计(如 WEUI、Bootstrap)
BEM 被广泛用于 UI 框架,确保样式隔离和可扩展性
- 响应式设计与主题切换
BEM 的修饰符可以轻松实现不同屏幕尺寸或主题的样式切换。
🌟总结
有了BEM命名规范,能让我们的代码变得更加健壮,主要体现在:
- 清晰的代码结构:通过
Block__Element--Modifier
的命名规则,让 HTML/CSS 更易读。 - 样式隔离:避免全局污染,减少命名冲突。
- 可维护性:修改组件时不会影响其他部分。
- 团队协作友好:统一规范,降低沟通成本。
下面是BEM命名规范的总结
类型 | 格式 | 示例 |
---|---|---|
Block | .block |
.header , .modal |
Element | .block__element |
.menu__item , .card__title |
Modifier | .block--modifier 或 .block__element--modifier |
.button--disabled , .tab__item--active |
如果项目简单,确实可以选择更轻量级的方案,但对于复杂的前端项目,BEM仍然是经过验证的可靠选择。
🌇结尾
感谢你看到最后,最后再说两点~
①如果你持有不同的看法,欢迎你在文章下方进行留言、评论。
②如果对你有帮助,或者你认可的话,欢迎给个小点赞,支持一下~
我是3Katrina,一个热爱编程的大三学生
(文章内容仅供学习参考,如有侵权,非常抱歉,请立即联系作者删除。)
作者:3Katrina
链接:https://juejin.cn/post/7509498122202382351
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。