BEM 的核心概念

从狭义上来讲,BEM 是一套 CSS 的命名规则,将 CSS 的命名分解为 Block, Element, Modifier 三个部分。本篇译文讲述 BEM 的核心概念,他的具体命名规则其它文章再做讲解。

原文地址

Block

页面上逻辑与功能独立的组件等同于 Wwb 组件。一个块中,封装了行为(JavaScript),模板,样式(CSS)和其它一些实现技术。一个独立的块可以被重用,以及推进项目的开发与维护

块的特性

结构嵌套

一个块可以嵌套在另一个块中。

比如,一个head块可以包含一个标识(logo),一个表单(form)和一个认证块(auth)。

Head 块组件

任意布局

一个块可以放置于页面的任意位置,并且在页面与项目之间迁移。因为块被当作一个独立的实体而存在,这使得他们可以在页面中的任意位置而不影响功能与外观。

因此,可以无需修改 CSS 与 JavaScript 代码便可将标识与认证块相互调换位置。
改变块的位置

一个界面可以包含很多相同块的实例。

Re use block

元素Element

不能用于之外的组成成分。

例如一个菜单项(menu item)不能在一个菜单块(menu block)外面使用,所以他是一个元素。
菜单项

修饰语Modifier

一个 BEM 实体定义了一个或者元素的外观与行为。

修饰语的使用并不是必须的。

修饰语本质与与 HTML 的属性(attribute)相似。同样的块因为使用了修饰语而变得不一样了。

比如,菜单块(menu)外观的改变依赖于他使用的修饰语。
底部加入一个菜单

BEM实体

元素修饰语被统称为 BEM 实体。

他可以代表一个单独的 BEM 实体,也可以作为块,元素与修饰语的一个通用术语。

混合

不同 BEM 实体被托管于同一个 DOM 节点所形成的实体。

混合允许我们做以下的事件:

  • 将一些 BEM 实体的行为与样式组合在一起,避免代码重复。
  • 在现有 BEM 实体的基础上创建新的语义化界面组件。

让我们想一想将一个块与另一个块中的元素混合的情况。

假设你项目中的链接都是通过link块实现的。现在我们需要将菜单项做成链接的样式,有以下两种方式:

  • 使用修饰语将菜单项转化成链接。实现这样的修饰语需要复制block块的行为与样式,从而导致代码重复。
  • 使用混合的方式将通过的link块与menu块的link元素组合起来。两个 BEM 实体的混合让我们可以无需复制代码,便能使用link块基本的链接功能和向menu块中添加 CSS 规则。

BEM

一个页面在结构方面表现为许多的块,元素与修饰语。这是 DOM 树的一种抽象表示,用来描述 BEM 实体的名称,状态,顺序,嵌套与辅助数据。

在实际项目中,BEM 树可以用任意的格式描述,但推荐使用树型结构。

假设有一个这样的 DOM 树:

类似的 BEM 树看起来可能是这样:

在 XML 与 BEMJSON 的语法格式中,相同的 BEM 树看起来是这个样子:

XML:

BEMJSON:

块的实现

有一套技术用来实现 BEM 实体的以下几个方面。

  • 行为
  • 外观
  • 测试
  • 模板
  • 说明文档
  • 依赖描述
  • 附加数据(比如 images)

实现技术

用来实现块的一系列技术。

  • 形为— JavaScript, CoffeeScript,TypeScript
  • 外观— CSS,Stylus, Sass,Less
  • 模板— BEMHTML, BH, Pug, Handlebars, XSL
  • 说明文档 — Markdown, Wiki,XML

比如,如果一个块的外观由 CSS 定义的,这意味着这个块使用了 CSS 技术实现。同样的,如果说明文档是使用 Markdown 语法格式编写,这个块也使用了 Markdown 技术实现。

块的重新定义

通过在不同的层级添加新特性,从而实现块的重新定义。

重定义层级

一系列 BEM 实体以及它们组成部分的实现

一个块的最后实现可以分解为不同的重定义层级。每个层级扩展或者重载块的原始实现。最终的结果由这个块的所有重定义层次的不同实现技术按预先定义好的顺序组装而成(就比如 CSS 层叠样式表)。

BEM 实体的任何实现技术都可以被重新定义

比如,项目在一个重定义层级引入一个第三方库,这个库包含一个现成的块实现。而项目本身的块被存储在另一个重定义层级。

假设我们需要修改其中一个第三方库中块的外观。我们不需要修改这个块在第三方库中的源代码或者在项目层级水平复制代码。我们只需要在项目层级水平为这个块添加额外的 CSS 规则。在构造的过程中,实施结果会同时包含库层级的原始规样式规则与项目层级的新样式规则。

发表评论

电子邮件地址不会被公开。 必填项已用*标注