這些原則都是我從這些年工作中所含蓋的各個大型、復雜的web項目中總結(jié)出來的。而這些事情也都是我這些年被多次問到的,所以覺得將其用文檔的形式敘述出來會是個不錯的想法。
我會嘗試著盡量縮短我的解釋,以下是關(guān)鍵詞:
善用類來定義CSS
將組件的相關(guān)代碼放在一起
使用一致的類命名空間
讓命名空間和文件名間具有映射關(guān)系
防止在組件外定義樣式
### 防止泄漏組件內(nèi)的樣式
考慮元素的邊界問題
松散的聚合外來樣式
簡介
如果你從事前端的應用開發(fā),那么你一定會需要設(shè)置樣式。盡管現(xiàn)在優(yōu)秀的前端應用花樣百出,但CSS仍然是賦予網(wǎng)頁上任何東西樣式的唯一方法(但是,在某些情況下,原生的應用也可以做到)。也就是說,這篇文章將講到兩大類設(shè)置樣式的方法,即:
已存在多年的 CSS 預處理器,如:SASS, LESS等)
相對而言,才出現(xiàn)的具有CSS-in-JS 特性的庫 (如 free-style, 和 many others)
對于這兩種方案的選擇完全可以另立文章進行講解。當然, 它們也都有各自的優(yōu)缺點。盡管如此,我將集中介紹前一種方法, 所以,如果你選擇“追隨”后者,那么這篇文章對于你而言會比較乏味。
高層次目標
我們追求的是一個穩(wěn)固的、可升縮的CSS框架。但是要做到這一點,究竟需要具備些什么特質(zhì)呢?
面向組件 - 處理UI復雜性的最佳方法就是講UI分成許多很小的組件。如果你使用了一個“明智的”框架,你就會發(fā)現(xiàn)在JS方面也是如此。 比如,React就具有高度組件化的特性。由此,我們希望CSS框架也能如此。
沙盒 - 將組建進行拆分并不一定能能使得其按照我們的期望進行加載,如:一個組件的樣式可能會對其他組件的樣式產(chǎn)生不可預計的影響。諸如cascade這樣的CSS基礎(chǔ)特性和具有唯一全局性性質(zhì)的命名空間的標識符就能造成這種影響。如果你對 Web組件的規(guī)范比較熟悉, 你就可以開始考慮利用 Shadow DOM可以隔離樣式的優(yōu)勢 來做些什么而不必去關(guān)心瀏覽器的支持程度(或是否有相應的規(guī)范)。
易用性 - 我們想要一切“漂亮”的事物,但是又不想做過多工作。也就是說,我們并不想要開發(fā)者在運用該框架時具有較差的體驗。如果可以,我們想將其做的更好。
容錯性 - 與前面的觀點有點聯(lián)系的是,我們希望一切的東西默認都具有本地性,當然,異常除外。而我們工程師都很懶,而通常阻力最小的方案總被證明是正確的解決方案。
一致性原則Concrete rules
1. 善用類來定義CSS
This is just to get the obvious out of the way.
不使用ID (e.g. #header
), 因為當你認為這將只是一個事物的實例的時候,你都會被現(xiàn)實-- 在無限的時間尺度上]--很扇一個耳光。這是我們過去發(fā)生過的一個案例。當時我們嘗試著去剔除一個大型應用中的數(shù)據(jù)綁定bug,因此我們在同一DOM樹中并列使用了兩個運用了這個UI庫的實例, 而這兩個都綁定到了一個名為shared的實例上。 最初,這是為了保證數(shù)據(jù)模型中的所有修改都能正確的反映到UI庫上。然而此時,任意你覺得會是獨一無二的組件,如:header bar,都將不復存在。這也是一個發(fā)現(xiàn)與獨特性假設(shè)相關(guān)的不易察覺的bug的標準方法。 這個事情的道理在于: 沒有相關(guān)的解決方法會使得運用ID的方法比運用class的方法好。 所以讓我們永遠不要使用ID吧。
同樣的,你也不能直接指定你的目標元素。 但是如果目標元素在某個組件里,直接指定到是可行。但最終,你需要去清除這些對于組件而言無用的樣式 。 而對于我們更高級別的目標來說,這與其是完全相背離的。而設(shè)置body上的屬性,如:fonts、 line-heights 和colors (又名可繼承的屬性) 卻是一個特例。 但是如果你格外在意組件的獨立性的話, 放棄這些是完全可行的(如 使用外在樣式中所說的一樣).
所以,除了某些特定的場合,你的樣式設(shè)置最好使用class。
2.將組件的相關(guān)代碼放在一起
當在設(shè)置一個組建的時候,如果能將其相關(guān)部分--js文件、css文件、測試文件等--聚集起來,會對組件的組件化起到很大的作用。