区块的定义是:一个逻辑和功能兼备的独立页面组件,也可以称为web组件。一个区块包含有行为(JS)、模板、样式(CSS)以及其他实现方法。由于区块有独立性,所以允许被重用,也可以适当促进项目开发的进程。
区块之间可被嵌套使用,例如:head
区块可以包含一个logo (logo
) 、一个搜索表单 (search
) 、以及一个认证模块 (auth
) 。
区块可以被放在页面的任何位置,也可以在页面或者项目之间相互移动。区块的实现靠的是独立的实体,所以允许开发着放在改变其位置,保证整体的功能和外观的效果。也就是说,不需要修改CSS或者任何JS代码,就可以让logo和认证表单两块交换位置。
允许多个相同的区块实例同时存在于一个界面里。
元素的定义是: 区块中无法被用在其他组件上的部分,例如:某个菜单子项是无法用于菜单区块以外的地方的,所以它属于元素。
区块或者元素的外观样式和行为,称为BEM实体。
是否使用修饰符,你可以自由选择。修饰符本质上和HTML的属性类似,相同的区块因为其使用的修饰符不同而不尽相同。例如:菜单区块的外观可能会因为其所依赖的修饰符变化而发生改变。
区块、元素、以及修饰符统称为BEM实体,这个概念既可以用于一个单独的BEM实体,也可以作为区块、元素和修饰符的整体概念。
它能帮我们
让我们来看看这样的情况:假设代码里的链接都是通过一个 link
区块实现的,现在,我们需要把菜单项都转为链接,有几种方法可以实现:
link
区块的行为和样式,代码就会重复;link
区块和一个 menu
区块里的 link
元素结合起来,在不复制代码之余,组合了两者的混合体又能保留它们各自的基础功能( link
的链接以及 menu
的CSS规则)。BEM树是一种由区块、元素和修饰符组成的网页结构,相对于DOM树(能表示BEM实体及其状态、排序、嵌套、附加代码等)来说,BEM树更像一种抽象概念。在实际项目中,BEM树可能以任何形式出现在树状结构里。让我们看看这个DOM树的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class=''logo''> =""> <="" span="">type=''input''>=""> <="" span="">class=''lang-switcher__item''>=""> <="" span="">class=''lang-switcher__item''>=""> |
对应的BEM树则是:
1 2 3 4 5 6 7 8 9 10 | header ├──logo └──search-form ├──input └──button └──lang-switcher └──lang-switcher__item └──lang-switcher__link └──lang-switcher__item └──lang-switcher__link |
对于同一个BEM树,XML 和BEMJSON的表达方式略有不同:
XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
BEMJSON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | { block: ''header'', content : [ { block : ''logo'' }, { block : ''search-form'', content : [ { block : ''input'' }, { block : ''button'' } ] }, { block : ''lang-switcher'', content : [ { elem : ''item'', content : [ { elem : ''link'' } ] }, { elem : ''item'', content : [ { elem : ''link'' } ] } ] } ] } |
不同的技术方法都可以决定一个BEM实体:
即用于实现区块的技术方法。
区块可以通过一种或多种方式实现,例如:
比如,一个区块的外观由CSS控制,也就可以说这个区块是用CSS技术实现的。同理,这个区块的文档由Markdown编写,就可以说这个区块也是用Markdown技术实现的。
即一系列BEM实体及其部分实现方式。
区块的最终实现方式可分为不同的重定义等级,每个新的等级扩展或覆盖的原有的实现方式,最终结果就是——该区块由各自独立的实现技术集合而成,并且其重定义等级都以预先指定的顺序排列。
BEM实体的任一实现方式都可以被重定义。例如,有个第三方的库在一个单独的级别上链接到项目中,这个库包含了一些现成的区块实现,而项目特有的区块则被放置在另一个重定义等级里。假如现在我们需要修改库中某个区块的样式,那么,不必修改库代码或者副本中的CSS,只需要在项目级别编写新的CSS规则即可。在编译过程中,最终的实现将会结合库原本的代码以及项目中的新代码两者的效果。
如果你在文中发现了任何错误,或者有需要帮助的地方,不要犹豫,请在GitHub上联系我们,或者在prose.io.发表勘误文章也是可以的。
联系客服