命名规范

一般情况下我都是以连字符(-)连接 class 的名字(例如 .foo-bar 而非 .foo_bar.fooBar),不过在某些特定的时候我会用 BEM(Block, Element, Modifier)命名法。

BEM 命名法可以使得选择器更规范,更清晰,更具语义。

该命名法按照如下格式:

  1. .block{}
  2. .block__element{}
  3. .block--modifier{}

其中:

  • .block 代表某个基本的抽象元素;
  • .block__element 代表构成 .block 的一个子元素;
  • .block—modifier 代表 .block 的某个不同状态或版本。打个比方:
  1. .person{}
  2. .person--woman{}
  3. .person__hand{}
  4. .person__hand--left{}
  5. .person__hand--right{}

这个例子中我们描述的基本元素是一个人,然后这个人可能是一个女人。我们还知道人拥有手,这些是人体的一部分,而手也有不同的状态,如同左手与右手。

这样我们就可以根据亲元素来划定选择器的命名空间并传达该选择器的职能,例如根据这个选择器是一个子元素(__)还是其亲元素的不同状态()。

由此,.page-wrapper 是一个独立的选择器。这是一个符合规范的命名,因为它不是其它元素的子元素或其它状态;然而 .widget-heading 则与其它对象有关联,它应当是 .widget 的子元素,所以我们应当将其重命名为 .widget__heading

BEM 命名法虽然不太好看,而且相当冗长,但是它使得我们可以通过名称快速获知元素的功能和元素之间的关系。与此同时,BEM 语法中的重复部分非常有利于 gzip 的压缩算法。

无论你是否使用 BEM 命名法,你都应当确保 class 命名得当,力保一字不多、一字不少;将元素命名抽象化以提高复用性(例如 .ui-list.media)。子元素的命名则要尽量精准(例如 .user-avatar-link)。不用担心 class 名的数量或长度,因为写得好的代码 gzip 也能有效压缩。

HTML 中的 class

为了确保易读性,在 HTML 标记中用两个空格隔开 class 名,例如:

  1. <div class="foo--bar bar__baz">

增加的空格应当可以使得在使用多个 class 时更易阅读与定位。

JavaScript 钩子

切勿将标记 CSS 样式的 class 用作 JavaScript 钩子。把 JS 行为与样式混在一起将无法对其分别处理。

如果你要把 JS 和某些标记绑定起来的话,写一个 JS 专用的 class。简单地说就是划定一个前缀 .js- 的命名空间,例如 .js-toggle.js-drag-and-drop。这意味着我们可以通过 class 同时绑定 JS 和 CSS 而不会因为冲突而引发麻烦。

  1. <th class="is-sortable js-is-sortable">
  2. </th>

上面的这个标记有两个 class,你可以用其中一个来给这个可排序的表格栏添加样式,用另一个添加排序功能。

I18n

虽然我(该 CSS Guideline 文档原作者 Harry Roberts)是个英国人,而且我一向拼写 colour 而非 color,但是为了追求统一,我认为在 CSS 中用美式拼法更佳。CSS 以及其它多数语言都是以美式拼法编写,所以如果在 .colour-picker{} 中写 color:red 就缺乏统一性。我以前主张同时用两种拼法,例如:

  1. .color-picker,
  2. .colour-picker{
  3. }

但是我最近参与了一份规模庞大的 Sass 项目,这个项目中有许多的颜色变量(例如 $brand-color$highlight-color 等等),每个变量要维护两种拼法实在辛苦,要查找并替换时也需要两倍的工作量。

所以为了统一,把所有的 class 与变量都以你参与的项目的惯用拼法命名即可。