修正於 2018-10-21。爲了文章生動,以前用了太多過於誇張的修飾手法,以致於讓不少朋友忽略了內容自己。基於網友的評論和指出的不足。略微修改了文風,刪除了多餘的廢話,梳理了文章大綱。css
命名 是我認爲 CSS 裏最難的問題沒有之一。html
CSS 是一個不強調邏輯,而更側重表現的一門所見即所得的語言。你寫了一個屬性它就有一個樣式,就比如嗑瓜子,你每嗑一下都能及時的獲得一個獎勵。這種愉悅感是別的開發語言所不具有的。前端
CSS 也不像其它側重邏輯的語言,有比較多的代碼管理方式。你能管理 CSS 的工具只有兩個,一個是文件引用,另外一個是命名。一般爲了減小頁面 HTTP 的請求,咱們會盡量的將 CSS 文件合併。因而靠文件引用這個方式來管理 CSS 的這條路也就顯得特別的窄了。react
咱們都知道 CSS 的做用域是全局的,只要你引用了一個 CSS 文件,它就會影響你整個頁面。因而,CSS 代碼管理的重任就全壓在了命名這一條路上。git
因此簡單的說,你能搞定 CSS 的命名,就能管理好 CSS。程序員
對於 CSS 的管理,我這邊舉個不恰當可是很貼切的類比,就是相似於平常生活中內褲的管理,是的就是平常穿的內褲,和 CSS 中的「類庫」諧音(我太有才了)。github
前面有講到,對於 CSS 的管理咱們基本只能經過命名的方式去管理。這聽起來彷佛是一件值得開心的事,由於只有一條路,因此你們都沒得選。然而出乎咱們意料的是,即便只有一條路,你們也是走得五花八門。web
舉個例子,好比咱們有 7 條不同的內褲,若是隻用命名的方式去管理內褲,會出現多少種可能?npm
按日期 | 按顏色 | 按材質 | 按花紋 | ... |
---|---|---|---|---|
.星期一{} |
.紅色{} |
.純棉{} |
.格子{} |
... |
.星期二{} |
.黃色{} |
.滌綸{} |
.橫條紋{} |
... |
.星期三{} |
.藍色{} |
.氨綸{} |
.波點{} |
... |
... |
... |
... |
... |
... |
就像一千個讀者就有一千個哈姆雷特同樣,不一樣的人對於同一件事物的命名方式是不同的。由於對於本身喜歡和熟悉的東西,對於其它的人來講都基本上是不熟悉的。不信你能夠問問你的同事,大家概括和命名內褲的方式很大機率是不同的。因此這個的可能性是無限的。編程
固然若是隻有 7 條內褲,你和個人命名方式不同就不同唄,我只要能看懂基本也就還好。但是,當咱們對於內褲的管理上升到了庫的概念的時候,一切就沒有那麼容易了。
假設你爸是挖礦的,你家頗有錢。而你又特別喜歡買內褲,赤,橙,黃,綠,青,藍,紫,彩色的,蕾絲的,莫代爾的,純棉的,緊身的... 各式各樣的內褲共計 100 ,請問你要怎麼命名這 100 條內褲?
此時你會發現上面管理 7 條內褲的方式,任意一個方式都顯得力不從心。因此要怎麼辦呢?
以前有講到,管理 CSS 的問題就是 CSS 命名的問題。因此咱們看看目前現有的最流行的解決 CSS 命名的通用解決方案 BEM。
由於我不是 BEM 的擁護者,以前舉的例子被網友評論打臉了,這邊就直接講結果吧。
.block__element--modifier{ /* */ }
複製代碼
很直觀的能夠看到引用了 BEM 以後,咱們的 CSS 就有了,三級的做用域。這個怎麼解釋呢?
很簡單,以前咱們命名 7 條內褲的方式是一維的。可是用 BEM 以後,能夠看做是一個長寬高各 10 的三維立方體。你要找一個東西,你只須要知道對應的長寬高對應的座標就能找到。相似:
.長1__寬2--高3{ /* */}
複製代碼
是否是一會兒就簡單了不少。BEM 系統的解決了 CSS 的命名問題,而且它的維護性和拓展性也是很是棒。因此它是很是值得推薦的管理 CSS 代碼的解決方案。感興趣的同窗能夠下來本身瞭解一下。
這裏呢,我是想說是我不喜歡 BEM 的點(感受又要打臉了)。與其說不喜歡 BEM,倒不如說我連 CSS 命名自己都不喜歡。爲何這麼說呢?由於對我來講命名真是一件很是痛苦的事情。
在我寫代碼的時候常常會遇到這樣的問題,有兩個很是像的模塊,可是它們又有些許的不一樣,爲了公用他們相同的樣式,你又必須將這部分抽象出來,但是抽象出來的這個部分,又不能傾向於這二者其中一個,你要怎麼命名呢?就比如:
/* 這個例子不是 BEM 的正確使用姿式,這裏只是做爲參考 */
.櫃1__屜2--內褲,.櫃2__屜2--內褲{
名稱:貼身的下身內衣;
大小:中號;
顏色:粉色;
}
.櫃1__屜2--內褲{
適合性別:男;
}
.櫃2__屜2--內褲{
適合性別:女;
款式:蕾絲;
}
<div style="櫃1__屜2--內褲">一條內褲</div>
<div style="櫃2__屜2--內褲">另外一條內褲</div>
複製代碼
你想爲上面這兩條內褲公共的部分抽象一個通用的類,請問要怎麼命名?而後更可怕的是,此時又來了第三條內褲:
.櫃2__屜3--內褲{
名稱:貼身的下身內衣;
大小:中號;
顏色:紅色;
適合性別:女;
款式:蕾絲;
}
<div style="櫃2__屜3--內褲">又一條內褲</div>
複製代碼
而後你又發現,以前好不容易命名好的通用類名,不能用到這第三條內褲上。然而第二條內褲和第三條內褲又有了公用的部分,這部分是否是又能夠進一步抽像呢?一旦抽象,就意味着又要取一個名字,然而此時你又該怎麼取名呢?此次拓展兩步,個人已經崩潰了。
固然在實際開發中,我相信你們有更優秀的命名方式,來解決這個實際的問題。這裏只是用這種誇張的方式來證實命名是一件很是不容易的事情(不用較真個人使用姿式是否正確)。
咱們每次找不到本身內褲的時候,會本能問:「媽!我昨天穿的那條內褲在哪兒啊?」
媽媽一般會不耐煩的回答:「昨天不就告訴你了在第一個櫃子的第二個抽屜,這樣的問題你到底還要問幾遍?」
.櫃1__屜2--內褲{
名稱:貼身的下身內衣;
大小:中號;
適合性別:男;
顏色:黑色;
}
複製代碼
「第一個櫃子第二抽屜」,這聽起來很像 BEM 命名的 的方式,固然它能很是簡單直白的告訴你內褲放在哪裏。
但是不知道你們有沒有想過這樣的問題,若是咱們問:「媽!我昨天穿的那條內褲在哪兒啊?」 啪!你媽媽直接就把內褲扔你臉上了,這種方式是否是纔是咱們更但願看到的結果。是的,要啥內褲座標啊,直接把內褲給我不就行了。我要的是內褲,不是內褲放在哪裏。
CSS 是什麼?CSS 是層疊樣式表,而 class
(類名)顯然不是,它只是 CSS 和 HTML 之間的鉤子。
名稱:貼身的下身內衣;
大小:中號;
適合性別:男;
顏色:黑色;
複製代碼
這些東西,纔是真正意義上的咱們想要的「內褲」的樣式。而.櫃1__屜2--內褲
只是一個告訴你 「內褲」 放在哪兒的座標。
那在實際開發過程當中,怎麼樣纔算是想要內褲的時候,內褲就出如今咱們手中呢?
<div style="名稱:貼身的下身內衣;大小:中號;顏色:粉色;適合性別:男;">一條內褲</div>
<div style="名稱:貼身的下身內衣;大小:中號;顏色:粉色;適合性別:女;款式:蕾絲;">另外一條內褲</div>
<div style="名稱:貼身的下身內衣;大小:中號;顏色:紅色;適合性別:女;款式:蕾絲;">又一條內褲</div>
複製代碼
是的,經過 style
直接寫 CSS 屬性,就能簡單粗暴的把「內褲放到別人手中」。而這也是我認爲最符合 CSS 「所見即所得」 的方式。
想要什麼樣式我就寫什麼樣式,不用花時間去爲個人樣式建立一個自認爲很好看,可是別人看不懂的類名。我也不用考慮命名污染的問題,由於根本連命名都沒有。也正由於連命名都沒有,因此也不須要糾結上面提到的任何關於命名讓人頭疼的問題。
只是由於咱們你們都太習慣建立 class
了,致使咱們在寫樣式的時候,第一步想不是樣式自己而是建立一個 class
。在我看來這是有一點本末倒置的。
總結一下就是:當我想要「內褲」的時候,我但願的是「內褲」就直接出如今個人手裏,而不是獲得一個能精確告訴我「內褲」放在哪裏的座標。無論這個座標的命名規則聽起來是有多麼的好。
一旦有了命名,我在管理 100 條「內褲」的同時,還得管理比「內褲」自己量級更復雜的這 100 個類名。
咱們之因此會須要去管理代碼,很大一部分緣由是由於咱們想要去複用它形成的。簡單的來講,現買現用,穿完就扔的內褲,是不須要你花時間和精力去管理的。
上一節中咱們放棄了複用樣式這個想法,利用 inline css,在解決代碼管理問題的同時,還獲得了一種將重心聚焦在 CSS 樣式自己的編程體驗。
正是由於咱們放棄了命名,因此才解決了代碼管理問題,但是想要複用就一定意味着要命名。這聽起來彷佛是一個悖論。
那有沒有一種方式是能夠跳出這個怪圈的呢?答案固然是有的,那就是放棄管理「內褲」,而是轉向去管理「內褲」的原材料。咱們將以前須要管理的 100 條內褲的原材料列舉以下:
基於以前的例子,咱們如今的代碼會變成什麼樣的呢?
<style> .貼身的下身內衣{ } .中號{ } .男{ } .女{ } .黑色{ } .紅色{ } .粉色{ } .蕾絲{ } </style>
<div class="貼身的下身內衣 中號 粉 男">一條內褲</div>
<div class="貼身的下身內衣 中號 粉色 女 蕾絲">另外一條內褲</div>
<div class="貼身的下身內衣 中號 紅色 女 蕾絲">又一條內褲</div>
<div class="紅色">一匹紅色的馬</div>
複製代碼
首先,由於這些原材料都已是不能拆分的最小單元,因此他們的名字能很是容易的固化下來,造成一個通用的「類庫」。每次建立新項目的時候,你只須要略微的修改就能夠複用起來。
雖然爲了解決樣式複用的問題咱們仍是有建立類名,但由於這些命名是不能夠拆分而且容易固化的,因此管理的難度會小不少。而且隨着,時間的推移,原材料的膨脹率是很是小的。組件化若是作得好,原材料甚至能夠作到只減不增。
更驚奇的是,這些原材料可不僅用於內褲上,它還能夠應用到衣服,褲子,鞋子...等等一系列的東西上。你甚至能夠用這個原材料,把一匹馬塗成紅色。這就是咱們視角改變了以後,整個思惟方式的巨大改變。而是將複用發揮到極致。
這種將樣式原子化的思惟方式,是來自雅虎團隊的 Atomic CSS (簡稱 ACSS )。絕不吹噓的說,基於這套理論,我是我遇到的前端程序員中 CSS 原型稿寫的最快的程序員(可能我認識的人原本就很少)。
在這裏有必要解釋一下,我全篇全部的論證都是基於「庫」的概念的。若是你只是建立一個簡單的運營活動頁 ACSS 那你只能用到 ACSS 快這一個特性,而它更大的優點代碼管理這一塊是體現不出來的。
由於組件化思惟正是當下最流行的時候。而 ACSS 是和組件化思惟特別 Match 的一種方式。因此特別但願 ACSS 能被你們看到。固然我的能力有限,若是不恰當的地方能夠給我留言,咱們一塊兒探討。
到這裏可能有的同窗會說,你這個原材料拆分的明顯沒對,布類型不是還有竹炭纖維,甚至太空材料的,顏色還有紅藍漸變或者五彩斑斕的黑。
對於咱們大多數男性程序員來講,內褲無非就是棉的和不是棉的兩種,顏色無非就是黑,白,灰。即便不是程序員,你也很難會發現,普通的人會買到,赤,橙,黃,綠,青,藍,紫這麼多種顏色的內褲。
舉這個例子是想說明什麼,內褲是工業品而不是藝術品。工業品註定會控制原材料的種類以下降成本的。而真正會把內褲當藝術品的人,也就不會由於沒錢,而不會去考慮複用內褲的問題。
在咱們網頁的開發也是同樣的,若是你的網站不是走藝術類的網站,你卻發現你的原材料提供商(設計師),光是從顏色上就給你提供了超過了十幾二十幾種顏色,那他必定是有問題的。
若是你的設計師,是對本身的設計語言是有極致約束能力的,那對於咱們開發者來講這真的是一件很是開心的事情。
更新於 2019/10/22
名稱 | NPM | github | CDN |
---|---|---|---|
@_nu/css-acss |
![]() |
![]() |
![]() |
講了這麼多,感受都只是空談理論。這邊我多年的使用經驗,總結的一個 ACSS 的 npm 類庫 @_nu/css-acss
供你們使用。
對於 ACSS, bootstrap, material-ui, github ... 都有相關的 類庫,而後整個 ** 類庫** 最完善的屬於 tailwindcss。固然他們都是基於 style-system
理論建立的。上手成本相對較高,且每每須要設計師的介入。
和這些項目相比,我這邊的方案,優勢在於簡單和極致的 CSS 開發體驗。簡單到整個邏輯只落點在命名規則,看完文檔 5 分鐘就會用,甚至徹底理解全部的邏輯。極致的 CSS 開發體驗,體如今熟悉這套規則以後,你會開始懷疑,你的手指速度慢於你思考 CSS 的速度。
固然爲了追求簡單和開發體驗這也是缺點,就是不夠完善,沒有處理相似 hover
,focus
... 等中間態,也沒有添加任何自定義的響應點。這部分須要你們基於本身項目和 命名規則 自由擴展。