如何管理 CSS 「內褲」

修正於 2018-10-21。爲了文章生動,以前用了太多過於誇張的修飾手法,以致於讓不少朋友忽略了內容自己。基於網友的評論和指出的不足。略微修改了文風,刪除了多餘的廢話,梳理了文章大綱。css

命名 是我認爲 CSS 裏最難的問題沒有之一。html

CSS 是一個不強調邏輯,而更側重表現的一門所見即所得的語言。你寫了一個屬性它就有一個樣式,就比如嗑瓜子,你每嗑一下都能及時的獲得一個獎勵。這種愉悅感是別的開發語言所不具有的。前端

CSS 也不像其它側重邏輯的語言,有比較多的代碼管理方式。你能管理 CSS 的工具只有兩個,一個是文件引用,另外一個是命名。一般爲了減小頁面 HTTP 的請求,咱們會盡量的將 CSS 文件合併。因而靠文件引用這個方式來管理 CSS 的這條路也就顯得特別的窄了。react

咱們都知道 CSS 的做用域是全局的,只要你引用了一個 CSS 文件,它就會影響你整個頁面。因而,CSS 代碼管理的重任就全壓在了命名這一條路上。git

因此簡單的說,你能搞定 CSS 的命名,就能管理好 CSS。程序員

管理 CSS 就比如管理「內褲」

對於 CSS 的管理,我這邊舉個不恰當可是很貼切的類比,就是相似於平常生活中內褲的管理,是的就是平常穿的內褲,和 CSS 中的「類庫」諧音(我太有才了)。github

前面有講到,對於 CSS 的管理咱們基本只能經過命名的方式去管理。這聽起來彷佛是一件值得開心的事,由於只有一條路,因此你們都沒得選。然而出乎咱們意料的是,即便只有一條路,你們也是走得五花八門。web

舉個例子,好比咱們有 7 條不同的內褲,若是隻用命名的方式去管理內褲,會出現多少種可能?npm

按日期 按顏色 按材質 按花紋 ...
.星期一{} .紅色{} .純棉{} .格子{} ...
.星期二{} .黃色{} .滌綸{} .橫條紋{} ...
.星期三{} .藍色{} .氨綸{} .波點{} ...
... ... ... ... ...

就像一千個讀者就有一千個哈姆雷特同樣,不一樣的人對於同一件事物的命名方式是不同的。由於對於本身喜歡和熟悉的東西,對於其它的人來講都基本上是不熟悉的。不信你能夠問問你的同事,大家概括和命名內褲的方式很大機率是不同的。因此這個的可能性是無限的。編程

固然若是隻有 7 條內褲,你和個人命名方式不同就不同唄,我只要能看懂基本也就還好。但是,當咱們對於內褲的管理上升到了的概念的時候,一切就沒有那麼容易了。

假設你爸是挖礦的,你家頗有錢。而你又特別喜歡買內褲,赤,橙,黃,綠,青,藍,紫,彩色的,蕾絲的,莫代爾的,純棉的,緊身的... 各式各樣的內褲共計 100 ,請問你要怎麼命名這 100 條內褲?

此時你會發現上面管理 7 條內褲的方式,任意一個方式都顯得力不從心。因此要怎麼辦呢?

管理 CSS 「內褲」 的通用方法

以前有講到,管理 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 能被你們看到。固然我的能力有限,若是不恰當的地方能夠給我留言,咱們一塊兒探討。

內褲是工業品不是藝術品

到這裏可能有的同窗會說,你這個原材料拆分的明顯沒對,布類型不是還有竹炭纖維,甚至太空材料的,顏色還有紅藍漸變或者五彩斑斕的黑。

對於咱們大多數男性程序員來講,內褲無非就是棉的和不是棉的兩種,顏色無非就是黑,白,灰。即便不是程序員,你也很難會發現,普通的人會買到,赤,橙,黃,綠,青,藍,紫這麼多種顏色的內褲。

舉這個例子是想說明什麼,內褲是工業品而不是藝術品。工業品註定會控制原材料的種類以下降成本的。而真正會把內褲當藝術品的人,也就不會由於沒錢,而不會去考慮複用內褲的問題。

在咱們網頁的開發也是同樣的,若是你的網站不是走藝術類的網站,你卻發現你的原材料提供商(設計師),光是從顏色上就給你提供了超過了十幾二十幾種顏色,那他必定是有問題的。

若是你的設計師,是對本身的設計語言是有極致約束能力的,那對於咱們開發者來講這真的是一件很是開心的事情。

相關閱讀

  1. quickLayout.css-快速構建結構兼容的web頁面 @張鑫旭
    男神做品,強推;
  2. 「英」在組件化浪潮中從新思考CSS @johnpolacek
    雖然是英文,可是網頁作得像PPT同樣,通俗易懂,強推;
  3. 「CSS思惟」組件化VS原子化 @ziven27
    個人一篇專門解釋「組件化思惟」 和 「原子化思惟」 區別的文章;
  4. ACSS 官網 @雅虎
    這個思惟最先應該是雅虎推出來的,最近他們有在推 React ACSS
  5. 關於HTML語義和前端架構 @大漠;
  6. 「譯」CSS通用類和「關注點分離」 @adamwathan;
  7. 「英」Styling React @SURVIVEJS;
  8. 「英」CSS最佳實踐探討 - Atomic CSS @smashingmagazine;

解決方案

更新於 2019/10/22

名稱 NPM github CDN
@_nu/css-acss
npm package
github
jsdelivr

講了這麼多,感受都只是空談理論。這邊我多年的使用經驗,總結的一個 ACSS 的 npm 類庫 @_nu/css-acss 供你們使用。

對於 ACSS, bootstrap, material-ui, github ... 都有相關的 類庫,而後整個 ** 類庫** 最完善的屬於 tailwindcss。固然他們都是基於 style-system 理論建立的。上手成本相對較高,且每每須要設計師的介入。

和這些項目相比,我這邊的方案,優勢在於簡單和極致的 CSS 開發體驗。簡單到整個邏輯只落點在命名規則,看完文檔 5 分鐘就會用,甚至徹底理解全部的邏輯。極致的 CSS 開發體驗,體如今熟悉這套規則以後,你會開始懷疑,你的手指速度慢於你思考 CSS 的速度。

固然爲了追求簡單和開發體驗這也是缺點,就是不夠完善,沒有處理相似 hover,focus... 等中間態,也沒有添加任何自定義的響應點。這部分須要你們基於本身項目和 命名規則 自由擴展。

相關文章
相關標籤/搜索