首頁 >web前端 >js教程 >BEM文法詳解

BEM文法詳解

php中世界最好的语言
php中世界最好的语言原創
2018-03-19 10:01:583471瀏覽

這次帶給大家BEM文法詳解,使用BEM文法的注意事項有哪些,以下就是實戰案例,一起來看一下。

BEM的意思是區塊(block)、元素(element)、修飾符(modifier),是由Yandex團隊提出的一種前端命名方法論。這個巧妙的命名方法讓你的CSS類別對其他開發者來說更加透明且更有意義。 BEM命名約定更加嚴格,而且包含更多的信息,它們用於一個團隊開發一個耗時的大專案。

重要的是要注意,我使用的基於BEM的命名方式是經過Nicolas Gallagher修改過的。這篇文章中介紹的這種命名技術並不是原始的BEM,但卻是我更喜歡的改良版。無論實際上使用了什麼樣的符號,它們其實都是基於同樣的BEM原則。

命名約定的模式如下:

.block{}.blockelement{}.block--modifier{}
  • .block 代表了更高層級的抽像或元件。

  • .blockelement 代表.block的後代,用於形成一個完整的.block的整體。

  • .block--modifier代表.block的不同狀態或不同版本。

之所以使用兩個連字符和底線而不是一個,是為了讓你自己的區塊可以用單一連字符來界定,如:

.site-search{} /* 块 */.site-searchfield{} /* 元素 */.site-search--full{} /* 修饰符 */

BEM的關鍵是光憑名字就可以告訴其他開發者某個標記是用來幹什麼的。透過瀏覽HTML程式碼中的class屬性,你就能夠明白模組之間是如何關聯的:有些僅僅是組件,有些則是這些組件的子孫或者是元素,還有一些是組件的其他形態或者是修飾符。我們用一個類比/模型來思考一下下面的這些元素是怎麼關聯的:

.person{}.personhand{}.person--female{}.person--femalehand{}.personhand--left{}

頂級區塊是‘person’,它擁有一些元素,如‘hand’。一個人也會有其他形態,例如女性,這種形態進而擁有它自己的元素。下面我們把他們寫成『常規』CSS:

.person{}.hand{}.female{}.female-hand{}.left-hand{}

這些『常規』CSS都是有意義的,但是它們之間卻有些脫節。就拿.female來說,是指女性人類還是某種雌性的動物?還有.hand,是在說一隻鐘錶的指針(譯註:英文中hand有指針的意思)?還是一隻正在玩紙牌的手?使用BEM我們可以獲得更多的描述和更清晰的結構,單單透過我們程式碼中的命名就能知道元素之間的關聯。 BEM真是強大。

再來看一個之前用『常規』方式命名的.site-search的例子:

<form class="site-search  full">
  <input type="text" class="field">
  <input type="Submit" value ="Search" class="button">
</form>

這些CSS類別名稱真是太不精確了,並不能告訴我們足夠的資訊。儘管我們可以用它們來完成工作,但它們確實非常含糊不清。用BEM記號法就會是下面這個樣子:

<form class="site-search  site-search--full">
  <input type="text" class="site-searchfield">
  <input type="Submit" value ="Search" class="site-searchbutton">
</form>

我們能清楚地看到有個叫.site-search的塊,他內部是一個叫.site -searchfield的元素。而.site-search還有另一種形態叫.site-search--full

我們再來舉個例子…

如果你熟悉OOCSS(物件導向CSS),那麼你對media物件一定也不陌生。用BEM的方式,media物件就會是下面這個樣子:

.media{}.mediaimg{}.mediaimg--rev{}.mediabody{}

從這個CSS的寫法上我們就已經知道.mediaimg.mediabody一定是位於.media內部的,而且.mediaimg--rev.mediaimg的另一種形態。光是透過CSS選擇器的名字我們就能取得以上全部資訊。

BEM的另一個好處是針對下面這種情況:

<p class="media">
  <img src="logo.png" alt="Foo Corp logo" class="img-rev">
  <p class="body">
    <h3 class="alpha">Welcome to Foo Corp</h3>
    <p class="lede">Foo Corp is the best, seriously!</p>
  </p>
</p>

光從上面的程式碼來看,我們根本不明白.media和.alpha兩個class彼此之間是如何相互關聯的?同樣我們也無從知曉.body和.lede之間,或.img-rev
和.media之間各是什麼關係?從這段HTML(除非你對那個media物件非常了解)我們也不知道這個元件是由什麼組成的和它還有什麼其他的形態。如果我們用BEM方式重寫這段程式碼:

<p class="media">
  <img src="logo.png" alt="Foo Corp logo" class="mediaimg--rev">
  <p class="mediabody">
    <h3 class="alpha">Welcome to Foo Corp</h3>
    <p class="lede">Foo Corp is the best, seriously!</p>
  </p>
</p>

我们立马就能明白.media是一个块,.mediaimg--rev是一个加了修饰符的.mediaimg的变体,它是属于.media的元素。而.mediabody是一个尚未被改变过的也是属于.media的元素。所有以上这些信息都通过它们的class名称就能明白,由此看来BEM确实非常实用。

丑极了!

通常人们会认为BEM这种写法难看。我敢说,如果你仅仅是因为这种代码看上去不怎么好看而羞于使用它,那么你将错失最重要的东西。除非使用BEM让代码增加了不必要的维护困难,或者这么做确实让代码更难读了,那么你在使用它之前就要三思而行了。但是,如果只是“看起来有点怪”而事实上是一种有效的手段,那么我们在开发之前当然应该充分考虑它。

是,BEM看上去确实怪怪的,但是它的好处远远超过它外观上的那点瑕疵。

BEM可能看上去有点滑稽,而且有可能导致我们输入更长的文本(大部分编辑器都有自动补全功能,而且gzip压缩将会让我们消除对文件体积的担忧),但是它依旧强大。

用还是不用BEM?

我在我的所有项目中都使用了BEM记号法,因为它的有效性已经被它自己一次又一次地证明。我也极力地建议别人使用BEM,因为它让所有东西之间的联系变得更加紧密,让团队甚至是你个人都能够更加容易地维护代码。

然而,当你真正使用BEM的时候,重要的是,请记住你没必要真的在每个地方都用上它。比如:

.caps{ text-transform:uppercase; }

这条CSS不属于任何一个BEM范畴,它仅仅只是一条单独的样式。

另一个没有使用BEM的例子是:

.site-logo{}

这是一个logo,我们可以把它写成BEM格式,像下面这样:

.header{}.headerlogo{}

但我们没必要这么做。使用BEM的诀窍是,你要知道什么时候哪些东西是应该写成BEM格式的。因为某些东西确实是位于一个块的内部,但这并不意味它就是BEM中所说的元素。这个例子中,网站logo完全是恰巧在.header的内部,它也有可能在侧边栏或是页脚里面。一个元素的范围可能开始于任何上下文,因此你要确定只在你需要用到BEM的地方你才使用它。再看一个例子:

<p class="content">
  <h1 class="contentheadline">Lorem ipsum dolor...</h1>
</p>

在这个例子里,我们也许仅仅只需要另一个class,可以叫它.headline;它的样式取决于它是如何被层叠的,因为它在.content的内部;或者它只是恰巧在.content的内部。如果它是后者(即恰巧在.content的内部,而不总是在)我们就不需要使用BEM。

然而,一切都有可能潜在地用到BEM。我们再来看一下.site-logo的例子,想象一下我们想要给网站增加一点圣诞节的气氛,所以我们想有一个圣诞版的logo。于是我们有了下面的代码:

.site-logo{}.site-logo--xmas{}

我们可以通过使用--修饰符来快速地为我们的代码构建另一个版本。

BEM最难的部分之一是明确作用域是从哪开始和到哪结束的,以及什么时候使用(不使用)它。随着接触的多了,有了经验积累,你慢慢就会知道怎么用,这些问题也不再是问题。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

在表单中button与input的区别

详谈css样式初始化 

js的自定义trim函数使用方法

以上是BEM文法詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn