我听说很多开发者厌恶 CSS。而在我的经验中,这往往是由于他们并没有花时间来学习 CSS。
CSS 算不上是最优美的『语言』,但迄今二十多年来,它都是美化 web 举足轻重的工具。从这点来说,也还算不错吧?
尽管如此,CSS 写得越多,你越容易发现一个巨大的弊端。
因为维护 CSS 真是老大难。
特别是那些写得差劲的 CSS 会很快变成程序员的噩梦。
这里向大家介绍一些命名规范,遵照这些规范可以省时省力,少走弯路。
如果你常写 JavaScript,那么你知道对变量使用驼峰式命名法(camel case)是一种惯例。
var redBox = document.getElementById('...')
这样很好,对吧?
但问题是这种命名法并不适用于 CSS。
请切忌以如下方式命名:
.redBox { border: 1px solid red; }
相应的,你可以这样写:
.red-box { border: 1px solid red; }
这是一种非常标准的 CSS 命名规范。也可以说更易读。
同时,这也和 CSS 属性名称保持了一致。
// Correct .some-class { font-weight: 10em // Wrong .some-class { fontWeight: 10em BEM 命名规范不一样的团队在写 CSS 选择器(CSS selectors)有不一样的方法。有些团队使用的是连字符分隔(hyphen delimiters)法,还有一些倾向于使用一种叫 BEM 的命名法,这种方法更加有条理。总的来说,这些 CSS 命名规范试图解决 3 类问题:仅从名字就能知道一个 CSS 选择器具体做什么从名字能大致清楚一个选择器可以在哪里使用从 CSS 类的名称可以看出它们之间的联系不知你是否见过这样的类名:.nav--secondary { .nav__header { }复制这就是 BEM 命名规范。向 5 岁小孩解释 BEM 规范BEM 规范试图将整个用户界面分解成一个个小的可重复使用的组件。让我们来看看下图:可是个足以得奖的火柴人呢 :)哎,可惜并不是 :(这个火柴人代表了一个组件,比如说一个设计区块。或许你已经猜到了 BEM 这里的 B 意为『区块』(‘Block’)。在实际中,这里『区块』可以表示一个网站导航、页眉、页脚或者其他一些设计区块。根据上述解释,那么这个组件的理想类名称即是 stick-man。组件的样式应写成这样:.stick-man { }复制在这里我们使用了连字符分隔法,很好!E 代表元素(Elements) BEM 中的 E 代表着元素。整体的区块设计往往并不是孤立的。比方说,这个火柴人有一个头部(head),两只漂亮的手臂(arms)和双脚(feet)。 这些 head、feet 和 arms 都是组件中的元素。它们可视作子组件(child components),也就是父组件的组成部分。 如果使用 BEM 命名规范的话,这些元素的类名都可以通过在两条下划线后加上元素名称来产生。比如说:.stick-man__head { }.stick-man__arms { .stick-man__feet { M 代表修饰符(Modifiers) M 在 BEM 命名法中代表修饰符。如果说这个火柴人有个 blue 或者 red 这样的修饰符怎么办呢?在现实场景里,这可能是一个 red 或者 blue 的按钮。这就是之前在讲的组件当中的限定修饰。 如果使用 BEM 的话,这些修饰符的类名都可以通过在两条连字符后加上元素名来产生。比如说:.stick-man--blue { .stick-man--red { }复制最后这个例子展示的是父组件加修饰符。不过这种情况并不经常出现。假如我们这个火柴人拥有另一个不一样的头部大小呢?一次元素被加上了修饰符。记住,元素指一个整体封装区块中的一个子组件。 .stick-man 表示区块(Block), .stick-man__head 表示元素(the element)。从上例可以看出,双连字符也可以这样使用:.stick-man__head--small { .stick-man__head--big { }复制重申一次,上例中使用的双连字符是用来指代修饰符的。这样你都明白了吧。这就是 BEM 的基本用法。个人来说,我在小项目中一般只用连字符分割法来写类名,在用户界面更复杂的项目中使用 BEM 方法。为何要使用命名规范?在计算机科学当中只有两类难题:缓存失效和命名 - Phil Karlton命名的确很难。所以我们要尽量把它变得容易点,也为以后维护代码省点时间。能正确命名 CSS 中的类名可以让你的代码变得更易理解和维护。如果你选择 BEM 命名规范,在看标记语言(markup)时就更容易看清各个设计组件/区块之间的关系。感觉不错吧?和 JavaScript 关联的 CSS 名称今天是 John 上班第一天。他拿到了如下一段 HTML 代码:<div class="siteNavigation"> </div>复制因为刚好读了这篇文章,John 意识到这种命名方法在 CSS 中不是最好的方法。于是他将代码修改成下面这样:<div class="site-navigation"> </div>复制看上去不错吧?不过 John 没想到的是,他把整个代码库搞砸了 ???为什么会这样?在 JavaScript 代码中,有一段是和之前的类名 siteNavigation 有关联的:// Javascript 代码 const nav = document.querySelector('.siteNavigation')复制由于类名的改变,nav 变量现在变成了 null。好忧桑。??为了防止这种情况发生,开发者们想了很多不同的策略。1. 使用 js- 类名一种减少这类 bug 的方法是使用 js- 的类名命名方法。用这种方法来表明这个 DOM 元素和 JavaScript 代码的关联。例如:<div class="site-navigation js-site-navigation">
不一样的团队在写 CSS 选择器(CSS selectors)有不一样的方法。有些团队使用的是连字符分隔(hyphen delimiters)法,还有一些倾向于使用一种叫 BEM 的命名法,这种方法更加有条理。
总的来说,这些 CSS 命名规范试图解决 3 类问题:
不知你是否见过这样的类名:
.nav--secondary { .nav__header { }
这就是 BEM 命名规范。
BEM 规范试图将整个用户界面分解成一个个小的可重复使用的组件。
让我们来看看下图:
可是个足以得奖的火柴人呢 :)
哎,可惜并不是 :(
这个火柴人代表了一个组件,比如说一个设计区块。
或许你已经猜到了 BEM 这里的 B 意为『区块』(‘Block’)。
在实际中,这里『区块』可以表示一个网站导航、页眉、页脚或者其他一些设计区块。
根据上述解释,那么这个组件的理想类名称即是 stick-man。
stick-man
组件的样式应写成这样:
.stick-man { }
在这里我们使用了连字符分隔法,很好!
E 代表元素(Elements)
BEM 中的 E 代表着元素。
整体的区块设计往往并不是孤立的。
比方说,这个火柴人有一个头部(head),两只漂亮的手臂(arms)和双脚(feet)。
head
arms
feet
这些 head、feet 和 arms 都是组件中的元素。它们可视作子组件(child components),也就是父组件的组成部分。 如果使用 BEM 命名规范的话,这些元素的类名都可以通过在两条下划线后加上元素名称来产生。
比如说:
.stick-man__head { }.stick-man__arms { .stick-man__feet { M 代表修饰符(Modifiers) M 在 BEM 命名法中代表修饰符。如果说这个火柴人有个 blue 或者 red 这样的修饰符怎么办呢?在现实场景里,这可能是一个 red 或者 blue 的按钮。这就是之前在讲的组件当中的限定修饰。 如果使用 BEM 的话,这些修饰符的类名都可以通过在两条连字符后加上元素名来产生。比如说:.stick-man--blue { .stick-man--red { }复制最后这个例子展示的是父组件加修饰符。不过这种情况并不经常出现。假如我们这个火柴人拥有另一个不一样的头部大小呢?一次元素被加上了修饰符。记住,元素指一个整体封装区块中的一个子组件。 .stick-man 表示区块(Block), .stick-man__head 表示元素(the element)。从上例可以看出,双连字符也可以这样使用:.stick-man__head--small { .stick-man__head--big { }复制重申一次,上例中使用的双连字符是用来指代修饰符的。这样你都明白了吧。这就是 BEM 的基本用法。个人来说,我在小项目中一般只用连字符分割法来写类名,在用户界面更复杂的项目中使用 BEM 方法。为何要使用命名规范?在计算机科学当中只有两类难题:缓存失效和命名 - Phil Karlton命名的确很难。所以我们要尽量把它变得容易点,也为以后维护代码省点时间。能正确命名 CSS 中的类名可以让你的代码变得更易理解和维护。如果你选择 BEM 命名规范,在看标记语言(markup)时就更容易看清各个设计组件/区块之间的关系。感觉不错吧?和 JavaScript 关联的 CSS 名称今天是 John 上班第一天。他拿到了如下一段 HTML 代码:<div class="siteNavigation"> </div>复制因为刚好读了这篇文章,John 意识到这种命名方法在 CSS 中不是最好的方法。于是他将代码修改成下面这样:<div class="site-navigation"> </div>复制看上去不错吧?不过 John 没想到的是,他把整个代码库搞砸了 ???为什么会这样?在 JavaScript 代码中,有一段是和之前的类名 siteNavigation 有关联的:// Javascript 代码 const nav = document.querySelector('.siteNavigation')复制由于类名的改变,nav 变量现在变成了 null。好忧桑。??为了防止这种情况发生,开发者们想了很多不同的策略。1. 使用 js- 类名一种减少这类 bug 的方法是使用 js- 的类名命名方法。用这种方法来表明这个 DOM 元素和 JavaScript 代码的关联。例如:<div class="site-navigation js-site-navigation">
M 在 BEM 命名法中代表修饰符。
如果说这个火柴人有个 blue 或者 red 这样的修饰符怎么办呢?
在现实场景里,这可能是一个 red 或者 blue 的按钮。这就是之前在讲的组件当中的限定修饰。
如果使用 BEM 的话,这些修饰符的类名都可以通过在两条连字符后加上元素名来产生。
.stick-man--blue { .stick-man--red { }
最后这个例子展示的是父组件加修饰符。不过这种情况并不经常出现。
假如我们这个火柴人拥有另一个不一样的头部大小呢?
一次元素被加上了修饰符。记住,元素指一个整体封装区块中的一个子组件。
.stick-man 表示区块(Block), .stick-man__head 表示元素(the element)。
.stick-man
Block
.stick-man__head
从上例可以看出,双连字符也可以这样使用:
.stick-man__head--small { .stick-man__head--big { }
重申一次,上例中使用的双连字符是用来指代修饰符的。
这样你都明白了吧。
这就是 BEM 的基本用法。
个人来说,我在小项目中一般只用连字符分割法来写类名,在用户界面更复杂的项目中使用 BEM 方法。
在计算机科学当中只有两类难题:缓存失效和命名 - Phil Karlton
命名的确很难。所以我们要尽量把它变得容易点,也为以后维护代码省点时间。
能正确命名 CSS 中的类名可以让你的代码变得更易理解和维护。
如果你选择 BEM 命名规范,在看标记语言(markup)时就更容易看清各个设计组件/区块之间的关系。
感觉不错吧?
今天是 John 上班第一天。
他拿到了如下一段 HTML 代码:
HTML
<div class="siteNavigation"> </div>
因为刚好读了这篇文章,John 意识到这种命名方法在 CSS 中不是最好的方法。于是他将代码修改成下面这样:
<div class="site-navigation"> </div>
看上去不错吧?
不过 John 没想到的是,他把整个代码库搞砸了 ???
为什么会这样?
在 JavaScript 代码中,有一段是和之前的类名 siteNavigation 有关联的:
siteNavigation
// Javascript 代码 const nav = document.querySelector('.siteNavigation')
由于类名的改变,nav 变量现在变成了 null。
nav
null
好忧桑。??
为了防止这种情况发生,开发者们想了很多不同的策略。
一种减少这类 bug 的方法是使用 js- 的类名命名方法。用这种方法来表明这个 DOM 元素和 JavaScript 代码的关联。
js-
例如:
<div class="site-navigation js-site-navigation">