重要概念
- Block(块,并不是平常说的块级元素中的块,而是指模块、组件)
- Element(元素 )
- Modifier(修饰符 )
- BEM entity(BEM 实体)
- Mix(混合体)
- BEM tree(BEM 树 )
- Block implementation(块实现 )
- Block implementation technology (块实现技术 )
- Block redefinition (块重定义 )
- Redifinition level(重定义等级 )
1. Block(块)
Block 是一个逻辑上和功能上独立的页面组件,等同于网页组件中的部件(等同于网页中的组件)。Block 封装了行为(Javascript)、模板、样式(CSS)和其他实现技术。独立状态的 Block 可供复用,并且促进项目开发和维护。
Block 的特点
嵌套式的构造
Block 可以被嵌套到任何其他 block 里面去。例如,一个头部 block 可以包含一个 logo、一个搜索表单和一个登录 block。
随意放置
Block 可以在一个页面内任意移动,也可以在页面之间或项目之间移动。Block 作为独立的实体来实现,这使得在页面上改变 block 的位置 并确保其功能和外观一切正常 成为可能。
因此,即使不修改 block 的 CSS 和 Javascript 代码,logo 和 登录表单 也可以到处切换(译者注:即 logo 和 登录表单 可以用在各个页面各个项目中)。
可复用
一个界面可以包含同一个 block 的几个实例。
2. Element(元素)
Element 是一个 block 的组成部分,它不能被拿到 block 的外面使用。例如,一个菜单项(a menu item )不会在一个菜单块(a menu block )范围之外使用,因此它是一个元素(element)。
什么时候应该用 block?什么时候应该用 element?(A block or an element: when should I use which? )
BEM 方法论不推荐大家在element 内使用 element(Using elements within elements is not recommended by the BEM methodology )
3. Modifier(修饰符)
Modifier 是一个 BEM 实体,它定义了一个 block 或 element 的外观和行为。
Modifier 可用也可不用(即不一定要用到 modifier)。
Modifier 本质上与 HTML 的属性很相似。同一个 block 会因为 modifier 的使用而 看起来与之前有所不同。
例如,菜单块(the menu block )的外观可能会因为在它身上用了一个 modifier 而改变。
4. BEM entity(BEM 实体)
Block,element 和 modifier 合起来就被成为 BEM entity。它是一个 既可以用来指代单独的 BEM 实体又可以作为 block、element 和 modifier 的总称的 概念。
5. Mix(混合体)
Mix 是被托管在(being hosted on)一个单独的 DOM 节点上的 不同 BEM 实体(混合而成)的一个实例。
Mix 允许我们:
- 把几个 BEM 实体的功能(behavior)和样式 组合在一起,同时避免重复代码
- 在现有的 BEM 实体的基础上 创建语义上的新界面组件。让我们想一下这种 mix 情形:把一个 block 与 另一个 block 的一个 element 组合在一起。
我们假设,项目里的链接(links)通过一个链接块(a link block)来实现。我们需要把菜单项(menu items )格式化成链接(links)。这里有几种实现方法:
- 创建一个 可以把菜单项(item)转变成链接(link)的 modifier。实现这样一个 modifier 即必然牵涉到 复制链接块的功能和样式。这样一来就会导致代码重复。
- 取一个 把一个通用的链接块(link block )与一个菜单块的一个链接元素(a link element ) 组合在一起的 mix。两个 BEM 实体的混合体(mix)可以让我们不用复制代码,就可以使用链接块的基本链接功能 和 菜单块的 CSS 规则。
6. BEM tree(BEM 树)
BEM tree 是网页结构在 block、element 和 modifier 方面的表示(representation)。这是一个在 DOM 树之上的抽象概念,它描述了 BEM 实体的名称、它们的状态、顺序、嵌套和辅助数据。在现实生活中的项目,BEM tree
可以呈现在任何支持树结构的形式(format)中。
让我们看一下 DOM 树的一个例子:
<header class="header">
<img class="logo">
<form class="search-form">
<input type="input">
<button type="button"></button>
</form>
<div class="lang-switcher"></div>
</header>
对应的 BEM tree 看起来是这样子的:
header
├──logo
└──search-form
├──input
└──button
└──lang-switcher
在 XML 和 BEMJSON 格式中,该 BEM tree 则是这样的:
XML
<block:header>
<block:logo/>
<block:search-form>
<block:input/>
<block:button/>
</block:search-form>
<block:lang-switcher/>
</block:header>
BEMJSON
{
block: 'header',
content : [
{ block : 'logo' },
{
block : 'search-form',
content : [
{ block : 'input' },
{ block : 'button' }
]
},
{ block : 'lang-switcher' }
]
}
7. Block implementation(BEM 实现)
Block implementation 是指一组各不相同的 技术,这些技术决定着 BEM 实体以下几方面:
- 行为/功能(behavior)
- 外观
- 测试
- 模板
- 文档(documentation)
- 依赖描述
- 附加数据(例如:图片)
8. Implementation technology(实现技术)
Implementation technology 是一种用于实现 一个 block 的技术。Block 可以用一种或多种技术来实现,例如:
- 行为/功能(behavior)-- JavaScript, CoffeeScript
- 外观-- CSS, Stylus, Sass
- 模板-- BEMHTML, BH, Jade, Handlebars, XSL
- 文档(documentation)-- Markdown, Wiki, XML
例如,如果一个 block 的外观是用 CSS 来定义的,这意味着 block 是用 CSS 技术实现的。同样地,如果一个 block 的文档是用 Markdown 格式写的,block 就是用 Markdown 技术来实现的。
9. Block redefinition(block 重定义)
Block implementation 是指通过在不同的层级上增加新的功能到 block
来修改 block
。
10. Redefinition level(重定义级别)
Redefinition level 是指一组 BEM 实体和它们的部分实现。
一个 block 的最终实现 可以被分成 不同的重定义层级。每一个新的层级都会扩展或覆盖原始的 block implementation。最终的结果由 来自所有按照预设的连续的顺序排列的重定义层级的独立的 block implementation technologies 组合而成。
任何 BEM 的实现技术都可以被重新定义。
例如,有一个连接到项目的第三方库。这个库包含现成的 block implementation。该项目指定的 block 保存在一个另一个重定义层级。比方说(Let's say ),我们需要修改这个库里的某一个 block 的外观。这并不需要在库的源代码里修改 block 的 CSS 规则 或者 在项目里复制代码。我们只需在项目里为 那一个 block 创建额外的 CSS 规则。在生成过程中,所产生的实现 将会结合 来自库的原始规则 与 来自项目的新样式。(原文喜欢用 library level 和 project level,但翻译的时候,直接理解为 library 和 project 就好)