作為一個前端,你敢說自己懂css,敢自信的說自己精通css嗎?css編寫很簡單,但是初期的結構設計,後期的維護是一項非常消耗腦力的事情。
在這裡,丟擲兩個名詞:oocss和BEM.
什麼是oocss?
還沒了解過的可以看這篇文章 OOCSS vs. OOSCSS
相信大家都用過bootstrap,bootstrap就是典型的物件導向css,即oocss.
物件導向的CSS是一種容易重用的一種CSS規則,這裡關鍵的一點就是如何在頁面中識別,建立和模組化可重用的物件,並在頁面中任何需要的地方重用,並擴充套件其附加功能。所以我的理解是,oocss是一種可重用,樣式分離,耦合度低的css.
缺點:
- OOCSS適合真正的大型網站開發,因為大型網站用到的可重用性元件特別的多,如果運用在小型專案中可能見不到什麼成效。所以用不用OOCSS應該根據你的專案來決定。
- 如果沒用巧妙的使用,建立元件可能對於你來說是一堆沒用的東西,成為一爛攤子,給你的維護帶來意想不到的杯具,說不定還是個維護的噩夢。
- 最好給每一個元件備寫一份說明文件,有助於呼叫與維護
- 建立了數千行CSS,但有可能這些CSS永遠不會被使用。比如Twitter Bootstrap
- 樣式(CSS)和結構(HTML)藕合太緊
優點:
- 強調重用,減少CSS程式碼
- 選擇器簡潔
- 可擴充套件類
- 強調風格與內容分離
- 強調內容與容器分離
- 具有清潔的HTML標記,有語義的類名,邏輯性強的層次關係
- 語義標記,有助於SEO
- 可擴充套件的標記和CSS樣式,有更多的元件可以放到庫中,而不影響其他的元件
舉個例子
//css寫法
.title-1{
border-bottom:1px solid #ccc;
font-size:16px;
font-weight:bold;
color:#333;
}
//OOCSS寫法
.bb-c{
border-bottom:1px solid #ccc;
}
.f16{
font-size:16px;
}
.bold{
font-weight:bold;
}
.c333{
color:#333;
}
//html
<div class="f16 bold c333 bb-c">標題</div>複製程式碼
然而,你會覺得這給html新增了太多的負擔,所以我更推薦使用oosass。
oosass是可伸縮,物件導向的CSS,其實它就是OOCSS的一個變異體,進化體。
oosass的特點:
- 沒有CSS,只有Sass
- 通過%placholder來宣告視覺物件
- 可以通過mixin建立可重複的CSS
- 語義化的類名在DOM中宣告,而視覺化類名在Sass中宣告,否則不可能使用CSS構建UI結構和框架
- 通過Sass來擴充套件類,而不是通過DOM來擴充套件類
舉個例子,上述程式碼可以變為:
%bb-c{
border-bottom:1px solid #ccc;
}
%f16{
font-size:16px;
}
%bold{
font-weight:bold;
}
%c333{
color:#333;
}
%c999{
color:#999;
}
.title-1{
@extend %bb-c;
@extend %f16;
@extend %bold;
@extend %c333;
}
//假設有類title-2
.title-2{
@extend %f16;
@extend %c999;
}複製程式碼
則生成的程式碼為:
.title-10 {
border-bottom: 1px solid #ccc;
}
.title-10,
.title-20 {
font-size: 16px;
}
.title-10 {
font-weight: bold;
}
.title-10 {
color: #333;
}
.title-20 {
color: #999;
}複製程式碼
值得注意的是,在動手寫oosass之前,一定要動腦好好想想怎麼構建自己的原子類庫,因為只要你的原子類足夠好,你後面的元件和頁面只需要extend原子類,程式碼基本不會有增加。原子庫的構建思路如下:
/**
* 原子類 - 文字控制
*/
%tl {
text-align: left;
}
%tr {
text-align: right;
}
%tc {
text-align: center;
}
/**
* 原子類 - 字型大小控制
*/
%f12 {
font-size: 12px;
}
%f14 {
font-size: 14px;
}
%f16 {
font-size: 16px;
}
%f18 {
font-size: 18px;
}
/**
* 原子類 - 定位
*/
%fl {
float: left;
}
%fr {
float: right;
}
%pr {
position: relative;
}
%pa {
position: absolute;
}複製程式碼
當然,如果你需要用到覆蓋的時候,就無法@extend了,因為原子類在最上層,優先順序不夠。
什麼是BEM?
BEM代表塊(Block),元素(Element),修飾符(Modifier)。
Block 是頁面中獨立存在的區塊,可以在不同場合下被重用。每個頁面都可以看做是多個Block組成。
Element 是構成Block的元素,只有在對應Block內部才具有意義,是依賴於Block的存在。
Modifier 是描述Block或Element的屬性或狀態。同一Block或Element可以有多個Modifier。
很多人對BEM的第一印象是:又長又醜,一點都不漂亮!
運用BEM思想的框架,網站:
餓了麼的框架elementUI就是BEM的一種,你也可以研究網站company.yandex.ru/
如果你沒接觸過BEM,可以檢視文章:BEM的定義
他的命名規範
下劃線和橫線
component-name
component-name--modifier-name
component-name__sub-object
component-name__sub-object--modifier-nam複製程式碼
駝峰
org-ComponentName
org-ComponentName--modifiername
org-ComponentName-subObject
org-ComponentName-subObject--modifiername複製程式碼
因為時常存在塊巢狀另一個塊的問題,可以使用字首來區分
p-頁面(Page) (應用於body元素的類),對可維護性不是那麼重要的靜態頁面十分有用 —應該避免巢狀使用 (例: p-Homepage);
l-佈局(Layout), 比如列(columning),包裹(wrappers) 和容器(containers)等等(例: l-Masthead, l-Footer);
c-元件(components )(例: c-Dropdown, c-Button…);
u-公共類(Utility classes) — 不會發生改變, 在程式碼的任何地方都不能過載。(例: u-textCenter, u-clearfix…);
js-JavaScript鉤子:永遠不應該出現在CSS中。
g-JavaScript鉤子:全域性js類,永遠不應該出現在CSS中複製程式碼
解決巢狀的思路可以參考文章:關於BEM中常見的十個問題以及如何避免
最佳實踐:
<div class="c-card">
<div class="c-card__header">
<h2 class="c-card__title">Title text here</h3>
</div>
<div class="c-card__body">
<p>I would like to buy:</p> <!-- Much nicer - a layout module -->
<ul class="l-list">
<li class="l-list__item"> <!-- A reusable nested component -->
<div class="c-checkbox">
<input id="option_1" type="checkbox" name="checkbox" class="c-checkbox__input">
<label for="option_1" class="c-checkbox__label">Apples</label>
</div>
</li>
<li class="l-list__item">
<div class="c-checkbox">
<input id="option_2" type="checkbox" name="checkbox" class="c-checkbox__input">
<label for="option_2" class="c-checkbox__label">Pears</label>
</div>
</li>
</ul> <!-- .l-list -->
</div> <!-- .c-card__body -->
</div> <!-- .c-card -->複製程式碼
優點
- 解決了名稱空間的問題
- 多人協作時,只要有文件清楚標註規則,後來人可以很輕易的讀懂,接手
- 更易於維護
缺點
- 容易寫的又長又醜
- 程式碼量比較多,沒這麼簡潔
- 需要完善的說明文件和規則
我的理解
個人覺得,如果從元件來說,使用BEM很不錯,定製化樣式就用oosass,兩者結合使用,純屬個人觀點,歡迎提出你的意見及實踐。畢竟我只是紙上談兵。
參考文件
www.w3cplus.com/preprocesso…
www.w3cplus.com/css/oocss-c…
segmentfault.com/a/119000000…
www.w3cplus.com/css/fifty-s…