如果你多年来关注我的作品,你会发现我一直痴迷于HTML的命名规则和尽量少写class。编写最简洁的HTML是我的信仰。

过去,我尽可能使用较短的class命名,比如我会像下面这样,使用CSS的属性选择器来替代class的显示声明。

a[title="Get Hardboiled"] { 
border-bottom : 5px solid #ebf4f6; }

我使用子选择器(配合>使用)直接定义元素子集的样式,在这个例子中,ul无序列表就是header元素的子集。

header > ul { 
list-style-type : none; 
display : flex; }

当然,我使用了很多相邻兄弟选择器。这种选择器可能已不再安全,它会把样式规则作用在近邻指定元素后方的元素上。比如下面的例子会对h1一级标题后的header元素增加一个蓝色的边框。

h1 + header { 
border-bottom : 5px solid #ebf4f6; }

甚至有一次,我制作了一个完全没有包含任何类属性的页面,什么都没有。每每想到这里,就很同情那些不得不靠很多class来构建页面的开发人员。

在过去的几年里,我们公司参与了几个大项目,这让我意识到,良好的代码结构、HTML和CSS元素之间的关系,对于项目交付是很重要的。BEM语法或者命名公约的作用就在于此。

区块、元素、装饰器

仔细看之前例子,你就会注意到,许多元素的属性值都有两条下划线或者俩个连字符。这些连字符和下划线是BEM系统的一部分,它们经常像下面这样使用。

.block用作高阶元素,包含了其他的内容和风格。例如在本书第一部分里,一个具有containerclass里面将包含一些子元素,包含一些主内容和互补内容。这个container就是典型的BEM区块。

.block__element代表这个元素是我们的子容器。主内容和互补内容边界就是很好的例子。用两个带下划线的元素就能描述它们的边界:.container__main.container__complementary。子元素或者特定的段落(如.container__lead)也可包含标题(如.container__heading)。

.block--modifier描述了对一个区块元素的改变。在本书网站的主页中,主容器是一个浅色背景,然而,一些属性改变了,它就变成了深色背景。我们可以通过有两个连字符的属性来做到,比如:container--dark

使用这个约定可以帮助精确定义不同元素之间的关系。开发人员可以通过检查HTML结构或者通过阅读我的样式表来理解。.container__main显然是容器的子元素。容器标题就是container__heading。开发人员不需要理解.container__dark的目的,因为BEM语法告诉他们,这是.container的一个标准替代。

使用BEM已经改变了我的工作,尽管我仍然追求简洁的HTML代码,但我可以为此牺牲一部分严谨的代码风格。

Stories from the UK

Stories from the USA

Stories from around the world

让我们继续增加一些文章来构建文档。