前言
為什么不用ID標(biāo)識(shí)符
主要考慮到樣式重用性以及與頁(yè)面的耦合性。ID本來(lái)就是唯一的而且權(quán)值那么大,還不如寫(xiě)在行內(nèi)樣式。
#button {
text-decoration: underline;
}
為什么不用大于三層嵌套選擇器
嵌套選擇器增加了代碼耦合,使重用變得不可能,過(guò)多的嵌套會(huì)導(dǎo)致顯示性能?下降。簡(jiǎn)潔的選擇器不僅可以減少css文件大小,提高頁(yè)面的加載性能,讓瀏覽器解析時(shí)也會(huì)更加高效。同時(shí)也會(huì)提高開(kāi)發(fā)人員的開(kāi)發(fā)效率,降低了維護(hù)成本。子代選擇器不好的地方還在于,如果層次關(guān)系過(guò)長(zhǎng),邏輯不清晰,非常不利于維護(hù)。
css的匹配原理不是從左到右的,而是從右到左的,從右邊開(kāi)始匹配是為了盡早過(guò)濾掉一些無(wú)關(guān)的樣式規(guī)則和元素。
.button_hovered .button__text {
text-decoration: underline;
}
為什么不用組合選擇器
組合選擇器的耦合性更強(qiáng),而且可維護(hù)性更加差。
.button.button_theme_islands {
text-decoration: underline;
}
介紹
BEM是Block,Element,Modifier的縮寫(xiě)。下面分別來(lái)介紹一下這三個(gè)概念:
- 塊(Block)是一個(gè)塊級(jí)元素,可以理解為組件塊,比如頭部是個(gè)block,內(nèi)容也是block,一個(gè)block可能由幾個(gè)子block組成。
- 元素(Element)element是block的一部分完成某種功能,element依賴(lài)于block,比如在logo中,img是logo的一個(gè)element,在菜單中,菜單項(xiàng)是菜單的一個(gè)element。
- 修飾符(Modifier)modifier是用來(lái)修飾block或者element的,它表示block或者element在外觀或行為上的改變,例如actived。
這里引用BEM的定義一文中的兩張圖:


我們通過(guò)BEM命名法寫(xiě)樣式如下:
- .block{}
- .block__element{}
- .block--modifier{}
- .block__element--modifier{}
BEM解決了的問(wèn)題,
- 頁(yè)面CSS模塊化,每個(gè)block就是一個(gè)模塊,模塊間相互獨(dú)立,不會(huì)造成污染
- 多級(jí)的class命名,避免選擇器的嵌套結(jié)構(gòu)
- 減少通配符*或者類(lèi)似[hidden="true"]這類(lèi)選擇器的使用
- 巧妙運(yùn)用scss的特性,保證了樣式的可維護(hù)性
BEM將頁(yè)面解析為block和element,然后根據(jù)不同的狀態(tài)使用modifier來(lái)設(shè)置樣式,在scss的屬性幫助下,其實(shí),寫(xiě)B(tài)EM并不麻煩。
使用scss寫(xiě)B(tài)EM
靈活的&
當(dāng)嵌套使用&時(shí),它會(huì)直接抓取父選擇器的類(lèi)名,自動(dòng)拼接上元素名字,避免CSS文件中組件樣式的沖突。這樣,我們可以得到一個(gè)完整的BEM結(jié)構(gòu)的類(lèi)名,這樣有效利用scss的嵌套特性避免CSS文件中組件樣式的沖突。
示例:
.header {
&__text {
text-decoration: underline;
}
&__image {
background-color: steelblue;
}
}
強(qiáng)大的@extend
@extend是scss的繼承語(yǔ)法,它可以將父級(jí)的屬性繼承到子級(jí)。主要使用在modifier上,因?yàn)楦淖儬顟B(tài)的屬性和原來(lái)的基本保持一致。你可以弄少一個(gè)classname。
示例:
<nav class="nav">
<ul class="nav__container">
<li class="nav__item"></li>
<li class="nav__item"></li>
<li class="nav__item"></li>
<li class="nav__item--active"></li>
</ul>
</nav>
.nav {
background-color: steelblue;
&__container {
display: flex;
justify-content: space-between;
}
&__item {
color: white;
&--active {
@extend .nav__item;
border-bottom: 1px solid red;
}
}
}