[譯] 多網站專案的 CSS 架構

?Badd發表於2019-07-26

多網站專案的 CSS 架構

CSS 架構 —— 第三部分

複雜的 CSS 架構,可不是你在科班裡能學到的東西。

我在網際網路行業的第四份工作,是在我國一家領先的媒體新聞公司中任職一名 CSS/HTML 專家,我的主要職責就是開發可重用的、可擴充套件的、用於多網站的 CSS 架構。

[譯] 多網站專案的 CSS 架構

在本文中,我將與大家分享我在構建多網站架構領域中積累的知識和經驗。

附註:如今,正規的專案都會用到 CSS 前處理器。而在本文中,我會使用 Sass 前處理器。

本文是我寫的討論 CSS 架構的系列文章中的第三篇。建議大家最好先讀讀此係列的第二篇 —— 《CSS 架構:資料夾和檔案結構》,有助於加深對本文的理解。

用層構建世界

在開始開發一個大型專案之前,我們應該放眼全域性,把多個網站的共同之處提煉出來。高樓大廈始於一磚一瓦,而專案的基石就是樣式規格化、混入(Mixins)、通用圖示以及區域性模組層(元素、元件、圖形邏輯、實體、頁面……不一而足)等。

為了使多重專案(即多個網站)正常運轉,我們必須決定哪些樣式是通用樣式、哪些是專有樣式 —— 通用樣式寫進基礎層,而專有樣式寫在與其對應的層中。這是一條充滿摸索和碰壁的實踐之路。每當思考的角度發生變化,我們都需要逐層地挪動樣式程式碼,直到我們覺得順眼為止,這都是家常便飯了。

理解了這項原則後,我們就可以開始著手構建作為基礎的全域性層了。這個全域性層是整個多重專案(多個網站)的起始點。

下面的示例圖向我們演示了彼時我司的專案需求。

層架構

基礎層要保持輕量,其中只包含 CSS 初始化、基本的 SASS mixins、通用圖示、通用字型(如需)以及功能類,如果某些網格佈局適用於所有網站,就將其作為通用網格新增到基礎層中。在 _partials.scss 層(元素、元件等)中,我們主要用到的是 _elements.scss 層,該層中包含諸如通用彈窗、通用表單和通用標題等此類區域性模組。我們應該在基礎樣式中新增的是所有(或者大多數)底層樣式共有的部分。(更多關於資料夾和檔案結構的細節,參見我的上一篇文章

如何組織多個層

在我們的架構中,每個層都至少包含三個檔案:兩個私有檔案(區域性樣式檔案和配置檔案,稱之為私有是因為它們不會被編譯成一個 CSS 檔案)和一個公共檔案(本層的主檔案)。每層的配置檔案 _config.scss 通常包含變數。_local.scss 檔案則包含內容樣式,為當前層充當控制器或者包管理器的角色。而第三個檔案(layer-name.scss)會呼叫前二者。

layer-name.scss 檔案:

@import "config";
@import "local";
複製程式碼

另外一個我們要給自己定下的原則就是,儘可能把每個檔案都拆分成儘可能小的部分(小檔案)。這個原則會讓重構非常方便。

在每一層中,都要保證只編譯 layer-name.scss 檔案,即使某些層代表的是一個“虛擬專案”(如上面示例圖中的“基礎層框架”)。

對於不會被編譯成單獨檔案的私有檔案,我們用一個下劃線(_)作為其檔名的字首。這裡的下劃線代表著此檔案不能單獨存在。

**注意:**當匯入私有檔案時,我們書寫其檔名時可以不必帶上字首下劃線。

層架構示例:

**_local.scss 檔案匯入了 local 資料夾中所有的 *.scss 檔案**,而這些 local 資料夾中的 *.scss 檔案按序呼叫私有資料夾中所有的 *.scss 檔案。同理,**_config.scss 檔案呼叫 config 資料夾中所有的 *.scss 檔案**。

資料夾結構長這樣:

sass/ 
 |
 |- base-layer/
     |- config/     
     |- local/
     |- _config.scss
     |- _local.scss
     |- base-layer.css  (編譯後的層樣式)
     |- base-layer.scss
複製程式碼

繼承

假設我們想要從基礎層開始建立一個專案。我們需要根據 base-layer 資料夾的內部結構,用新專案的名稱照貓畫虎地克隆一套出來。在後續例子中,我們把這個新專案稱為 inherited-project

提示:把所有的層目錄和專案目錄都放在 Sass 的根目錄中。

該專案至少包含一個 _config.scss 檔案、一個 _local.scss 檔案和此層的核心 Sass 檔案 —— 在本例中即為 inherited-project.scss

所有的層和專案都位於 Sass 的根目錄中。

sass/ 
 |
 |- base-layer
 |   |- config/     
 |   |- local/
 |   |- _config.scss
 |   |- _local.scss
 |   |- base-layer.css  (編譯後的層樣式)
 |   |- base-layer.scss 
 |
 |- inherited-project
     |- config/     
     |- local/
     |- _config.scss
     |- _local.scss
     |- inherited-project.css  (編譯後的層樣式)
     |- inherited-project.scss
複製程式碼

專案 inherited-project 的配置檔案引入了 base-layer 中的配置檔案。這樣一來,我們就能增加新變數或者覆寫上層(base-layer)中的已有變數了。

以下為 inherited-project/_config.scss 的一個例子

/*載入 base-layer 配置資訊 */
@import "../base-layer/config.scss";

/** 區域性的 Config 層 (按需新增或覆寫變數)**/
@import "config/directions.scss";
複製程式碼

內容樣式檔案 inherited-project/_local.scss 亦同理:

/* 匯入 base-layer 區域性元件  */
@import "../base-layer/local.scss";

/* 區域性字型 */
@import "local/font-almoni.scss";

/* 區域性元件 */
@import "local/elements.scss";
@import "local/components.scss";
複製程式碼

如果要建立的新層既有通用樣式又有獨特樣式,那麼從 base-layer 資料夾繼承基礎層樣式再合適不過了。

這一層會建立一個名為 inherited-project.css 的 CSS 檔案。

在內部層中覆寫變數

使用“層”的方式覆寫變數非常簡單。

比方說在基礎層中有一個名為 $base-color 的變數,其值為 blue($base-color: blue;)。要想覆寫此變數,就需要在區域性檔案 _config.scss 中更新它的值。現在,所有使用該變數的元件 —— 不論是繼承於基礎層還是定義於區域性層 —— 都會更新對應變數的的顏色值。

Global Story 全域性

某些模組並非在所有層中都會用到,因此如果你在基礎層中定義它們,其他專案就會匯入冗餘程式碼。為了解決這個問題,我走了另一條路線,採用了全域性模組的概念。

這個概念是說,把僅用於某些層的模組放置於一個新的根目錄(_partials)中,這個新的根目錄位於所有層之外。然後,任何層都可以從全域性目錄 _partials 中匯入所需模組。

下圖展示了將模組分離的例子:

[譯] 多網站專案的 CSS 架構

每一層都可以按需從全域性目錄 _partials 中呼叫一個或多個模組。

全域性目錄 _partials 示例:

sass/ 
 |
 |- _partials/ 
 |- base-layer/ 
 |- inherited-project/
複製程式碼

_partials 匯入模組的 local.scss 檔案:

/* 匯入 base-layer 中的區域性元件 */
@import "../base-layer/local.scss";

/* 區域性元件 */
@import "local/partials.scss";

/* 新增全域性模組 */
@import "../_partials/last-connection";
複製程式碼

些許額外忠告

  • 組織結構要有條理。要一直記得以滿足需求的方式規劃專案、保持最佳結構。
  • 別重蹈覆轍。僅用 @import 即可輕鬆匯入另一層的元件。比如說,某些元件定義在一個“體育”專案中,而這些元件與另一個專案中的“新聞”網站有關聯。那我們就可以直接把這些元件 @import 進“新聞”網站中。(網站 = 層 = 專案)
  • 充分利用 IDE 快捷方式。選用一款便於重構的編輯器,免於導致報錯或故障。
  • 立新不可破舊。在開發和後續重構中,每次都要把所有 Sass 根檔案一同編譯,以免新舊脫節。

總結

在本文中,我向大家展示了針對多網站專案的 CSS 體系結構的構建方法,這套思想提煉於我經年積累的知識和經驗。

本文是系列文章 CSS 架構文章新篇的第三篇,我會每隔幾周跟大家分享後續篇章。

如果覺得本文有趣,歡迎在 twitter 上或者 medium 上關注我。

我的 CSS 架構系列文章:

  1. 規格化 CSS 還是 CSS 重置?!
  2. CSS 架構 —— 資料夾和檔案架構
  3. 多網站專案的 CSS 架構

結束語

好了,這次就分享到這裡。 衷心希望大家喜歡本文,並能從我的經驗中獲益一二。 如果你喜歡本文,請點贊並和大家分享你的心得,我將不勝感激。:-)

如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章