BEM 是基于组件的 web 开发方法. 其思想是将用户界面分隔为独立的块, 从而使开发复杂的 UI 界面变得更简单和快, 且不需要粘贴复制便可复用现有代码. BEM 由 Block,Element,Modifier 组成. 选择器里用以下连接符扩展他们的关系:
`__: 双下划线用来连接块和块的子元素
` : 仅作为连字符使用, 连接块或元素或修饰符的多个单词 (也可以直接写成驼峰式)
--: 双中划线用来连接块或元素的状态 (也可使用'_'单下划线表示)
示例: block-name_modifier-name block-name__element-name--modifier-name block-name_modifier-name--modifier-value block-name__element-name--modifier-name--modifier-value
基本概念
Block(块)
代码片段可能被复用且这段代码不依赖其他组件即可用 Block. 块可以互相嵌套, 可以嵌套任意多层.
特点:
块的名称用于描述它的目的. 如 menu,button
块不能影响所在环境. 这意味着不能为块设置 margin 或 position
只能使用 class 命名选择器, 而不能使用标签或 id 选择器
不依赖于页面内其他块或元素
Element(元素)
Element 是 Block 的一部分, 没有独立存在的意义. 任何一个 Element 语义上是和 Block 绑定的.
特点:
与块使用'__'连接. 如: block__item
用于描述它的目的. 如: item,text
元素可以彼此嵌套, 可以嵌套任意多层
元素总是属于块的一部分. 所以类似于 block__item1__item2 的命名是不合法的
Modifier(修饰符)
Modifier 是 Block 或 Element 上的标记. 使用它们来改变样式, 行为或状态. 与块或元素连接符为'--'.
应用
相对另外的 Blocks 定位 Block
最好的方式是混合使用 block 和 element. 解决 block 上不能设置 margin,position. 例:
- <body class="page">
- <!-- header and navigation-->
- <header class="header page__header">...</header>
- <!-- footer -->
- <footer class="footer page__footer">...</footer>
- </body>
- .page__header {
- padding: 20px;
- }
- .page__footer {
- padding: 50px;
- }
Block 内定位 Elements
通过额外创建 Block 的子 Element 来定位嵌套. 例:
- <body class="page">
- <div class="page__inner">
- <!-- header and navigation-->
- <header class="header">...</header>
- <!-- footer -->
- <footer class="footer">...</footer>
- </div>
- </body>
- .page__inner {
- margin-right: auto;
- margin-left: auto;
- width: 960px;
- }
关于命名
选择器的命名必须完整且精确地描述它代表的 BEM 实体. 例:
- .button {
- }
- .button__icon {
- }
- .button__text {
- }
- .button_theme_islands {
- }
我们可直接指导我们在处理一个块元素. 在 html 使用如:
- <button class="button button_theme_islands">
- <span class="button__icon"></span>
- <span class="button__text">...</span>
- </button>
而下面的 CSS 就很难让我们做出相同的判断:
- .button {
- }
- .icon {
- }
- .text {
- }
- .theme_islands {
- }
在我的 Git 项目 miniui 中采用了 BEM 规范, 使用 Sass 实现了 BEM. 有兴趣可以查看: https://github.com/banyaner/miniui
参考: https://en.bem.info
来源: https://juejin.im/post/5c16096b6fb9a049e41299b4