CSS命名规范——BEM思想(⾮常赞的规范)
⼈们问我最多的问题之⼀是在CSS类名中“--”和“__”是什么意思?它们的出现是源于和...
BEM的意思就是块(block)、元素(element)、修饰符(modifier),是由团队提出的⼀种前端命名⽅法论。这种巧妙的命名⽅法让你的CSS类对其他开发者来说更加透明⽽且更有意义。BEM命名约定更加严格,⽽且包含更多的信息,它们⽤于⼀个团队开发⼀个耗时的⼤项⽬。
重要的是要注意,我使⽤的基于BEM的命名⽅式是经过。这篇⽂章中介绍的这种命名技术并不是原始的BEM,但却是⼀个我更喜欢的改进版。⽆论实际使⽤了什么样的符号,它们其实都是基于同样的BEM原则。
命名约定的模式如下:
[css]
1. .block{}
2. .block__element{}
3. .block--modifier{}
.block 代表了更⾼级别的抽象或组件。
.block__element 代表.block的后代,⽤于形成⼀个完整的.block的整体。
.block--modifier代表.block的不同状态或不同版本。
之所以使⽤两个连字符和下划线⽽不是⼀个,是为了让你⾃⼰的块可以⽤单个连字符来界定,如:
[css]
1. .site-search{} /* 块 */
2. .site-search__field{} /* 元素 */
3. .site-search--full{} /* 修饰符 */
BEM的关键是光凭名字就可以告诉其他开发者某个标记是⽤来⼲什么的。通过浏览HTML代码中的class属性,你就能够明⽩模块之间是如何关联的:有⼀些仅仅是组件,有⼀些则是这些组件的⼦孙或者是元素,还有⼀些是组件的其他形态或者是修饰符。我们⽤⼀个类⽐/模型来思考⼀下下⾯的这些元素是怎么关联的:
[css]
1. .person{}
2. .person__hand{}
3. .person--female{}
4. .person--female__hand{}
5. .person__hand--left{}
顶级块是‘person’,它拥有⼀些元素,如‘hand’。⼀个⼈也会有其他形态,⽐如⼥性,这种形态进⽽也会拥有它⾃⼰的元素。下⾯我们把他们写成‘常规’CSS:
[css]
1. .person{}
2. .hand{}
3. .female{}
4. .female-hand{}
5. .left-hand{}
这些‘常规’CSS都是有意义的,但是它们之间却有些脱节。就拿.female来说,是指⼥性⼈类还是某种雌性的动物?还有.hand,是在说⼀只钟表的指针(译注:英⽂中hand有指针的意思)?还是⼀只正在玩纸牌的⼿?使⽤BEM我们可以获得更多的描述和更加清晰的结构,单单通过我们代码中的命名就能知道元素之间的关联。BEM真是强⼤。
再来看⼀个之前⽤‘常规’⽅式命名的.site-search的例⼦:
[html]
1. <form class="site-search full">
2. <input type="text" class="field">
3. <input type="Submit" value ="Search" class="button">
4. </form>
这些CSS类名真是太不精确了,并不能告诉我们⾜够的信息。尽管我们可以⽤它们来完成⼯作,但它们确实⾮常含糊不清。⽤BEM记号法就会是下⾯这个样⼦:
[html]
1. <form class="site-search site-search--full">
2. <input type="text" class="site-search__field">
3. <input type="Submit" value ="Search" class="site-search__button">
4. </form>
我们能清晰地看到有个叫.site-search的块,他内部是⼀个叫.site-search__field的元素。并且.site-search还有另外⼀种形态叫.site-search--full。
我们再来举个例⼦……
如果你熟悉OOCSS(⾯向对象CSS),那么你对⼀定也不陌⽣。⽤BEM的⽅式,media对象就会是下⾯这个样⼦:
[html]
1. .media{}
2. .media__img{}
3. .media__img--rev{}
4. .media__body{}
从这种CSS的写法上我们就已经知道.media__img 和.media__body⼀定是位于.media内部的,⽽且.media__img--rev是.media__img的另⼀种形态。仅仅通过CSS选择器的名字我们就能获取到以上全部信息。
BEM的另外⼀个好处是针对下⾯这种情况:
[html]
1. <div class="media">
2. <img src="logo.png" alt="Foo Corp logo" class="img-rev">
3. <div class="body">
4. <h3 class="alpha">Welcome to Foo Corp</h3>
5. <p class="lede">Foo Corp is the best, seriously!</p>
6. </div>
7. </div>
光从上⾯的代码来看,我们根本不明⽩.media和.alpha两个class彼此之间是如何相互关联的?同样我们也⽆从知晓.body和.lede之间,或者.img-rev 和.media之间各是什么关系?从这段HTML(除⾮你对那个media对象⾮常了解)中我们也不知道这个组件是由什么组成的和它还有什么其他的形态。如果我们⽤BEM⽅式重写这段代码:
[html]
1. <div class="media">
2. <img src="logo.png" alt="Foo Corp logo" class="media__img--rev">
好看的css代码3. <div class="media__body">
4. <h3 class="alpha">Welcome to Foo Corp</h3>
5. <p class="lede">Foo Corp is the best, seriously!</p>
6. </div>
7. </div>
我们⽴马就能明⽩.media是⼀个块,.media__img--rev是⼀个加了修饰符的.media__img的变体,它是属于.media的元素。⽽.media__body 是⼀个尚未被改变过的也是属于.media的元素。所有以上这些信息都通过它们的class名称就能明⽩,由此看来BEM确实⾮常实⽤。
丑极了!
通常⼈们会认为BEM这种写法难看。我敢说,如果你仅仅是因为这种代码看上去不怎么好看⽽羞于使⽤它,那么你将错失最重要的东西。除⾮使⽤BEM让代码增加了不必要的维护困难,或者这么做确实让代码更难读了,那么你在使⽤它之前就要三思⽽⾏了。但是,如果只是“看起来有点怪”⽽事实上是⼀种有效的⼿段,那么我们在开发之前当然应该充分考虑它。
是,BEM看上去确实怪怪的,但是它的好处远远超过它外观上的那点瑕疵。
BEM可能看上去有点滑稽,⽽且有可能导致我们输⼊更长的⽂本(⼤部分编辑器都有⾃动补全功能,⽽且gzip压缩将会让我们消除对⽂件体积的担忧),但是它依旧强⼤。
⽤还是不⽤BEM?
我在我的所有项⽬中都使⽤了BEM记号法,因为它的有效性已经被它⾃⼰⼀次⼜⼀次地证明。我也极⼒地建议别⼈使⽤BEM,因为它让所有东西之间的联系变得更加紧密,让团队甚⾄是你个⼈都能够更加容易地维护代码。
然⽽,当你真正使⽤BEM的时候,重要的是,请记住你没必要真的在每个地⽅都⽤上它。⽐如:
[css]
1. .caps{ text-transform:uppercase; }
这条CSS不属于任何⼀个BEM范畴,它仅仅只是⼀条单独的样式。
另⼀个没有使⽤BEM的例⼦是:
[css]
1. .site-logo{}
这是⼀个logo,我们可以把它写成BEM格式,像下⾯这样:
[css]
1. .header{}
2. .header__logo{}
但我们没必要这么做。使⽤BEM的诀窍是,你要知道什么时候哪些东西是应该写成BEM格式的。因为某些东西确实是位于⼀个块的内部,但这并不意味它就是BEM中所说的元素。这个例⼦中,⽹站logo完全是恰巧在.header的内部,它也有可能在侧边栏或是页脚⾥⾯。⼀个元素的范围可能开始于任何上下⽂,因此你要确定只在你需要⽤到BEM的地⽅你才使⽤它。再看⼀个例⼦:
[html]
1. <div class="content">
2. <h1 class="content__headline">Lorem </h1>
3. </div>
在这个例⼦⾥,我们也许仅仅只需要另⼀个class,可以叫它.headline;它的样式取决于它是如何被层叠的,因为它在.content的内部;或者它只是恰巧在.content的内部。如果它是后者(即恰巧在.content的内部,⽽不总是在)我们就不需要使⽤BEM。
然⽽,⼀切都有可能潜在地⽤到BEM。我们再来看⼀下.site-logo的例⼦,想象⼀下我们想要给⽹站增加⼀点圣诞节的⽓氛,所以我们想有⼀个圣诞版的logo。于是我们有了下⾯的代码:
[css]
1. .site-logo{}
2. .site-logo--xmas{}
我们可以通过使⽤--修饰符来快速地为我们的代码构建另⼀个版本。
BEM最难的部分之⼀是明确作⽤域是从哪开始和到哪结束的,以及什么时候使⽤(不使⽤)它。随着接触的多了,有了经验积累,你慢慢就会知道怎么⽤,这些问题也不再是问题。
结束语
所以,BEM(或BEM的变体)是⼀个⾮常有⽤,强⼤,简单的命名约定,以⾄于让你的前端代码更容易阅读和理解,更容易协作,更容易控制,更加健壮和明确⽽且更加严密。
尽管BEM看上去多少有点奇怪,但是⽆论什么项⽬,它对前端开发者都是⼀个巨有价值的⼯具。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论