組織你的 CSS

當你開始處理更大的樣式表和大型專案時,你會發現維護一個巨大的 CSS 檔案可能具有挑戰性。在本文中,我們將簡要介紹一些編寫 CSS 的最佳實踐,以使其易於維護,以及一些你將發現其他人正在使用的解決方案,以幫助提高可維護性。

先決條件 已安裝基本軟體處理檔案的基本知識,HTML 基礎(學習HTML 簡介),以及 CSS 工作原理的概念(學習CSS 初步)。
目標 學習一些組織樣式表的技巧和最佳實踐,並瞭解一些常用的命名約定和工具,以幫助組織 CSS 和團隊協作。

保持 CSS 整潔的技巧

以下是一些關於如何保持樣式表井井有條的通用建議。

你的專案是否有編碼風格指南?

如果你與團隊合作處理現有專案,首先要檢查專案是否已存在 CSS 風格指南。團隊風格指南應始終優先於你自己的個人偏好。通常沒有正確或錯誤的方法,但一致性很重要。

例如,檢視MDN 程式碼示例的 CSS 指南

保持一致

如果你可以為專案設定規則或獨自工作,那麼最重要的事情是保持一致性。一致性可以透過各種方式應用,例如對類使用相同的命名約定,選擇一種描述顏色的方法,或保持一致的格式。(例如,你將使用製表符還是空格縮排你的程式碼?如果是空格,則使用多少個空格?)

有一套你始終遵循的規則減少了編寫 CSS 時所需的認知負擔,因為某些決策已經做出。

格式化可讀的 CSS

你會看到幾種 CSS 格式化方式。一些開發者將所有規則放在一行上,如下所示

css
.box {background-color: #567895; }
h2 {background-color: black; color: white; }

其他開發者更喜歡將所有內容都換行

css
.box {
  background-color: #567895;
}

h2 {
  background-color: black;
  color: white;
}

CSS 不在乎你使用哪一種。我們個人認為,將每個屬性和值對都換行更具可讀性。

註釋你的 CSS

向你的 CSS 添加註釋將有助於任何未來的開發者使用你的 CSS 檔案,但當你休息後返回專案時,它也會對你有所幫助。

css
/* This is a CSS comment
It can be broken onto multiple lines. */

一個好的技巧是在樣式表中邏輯部分之間添加註釋塊,以幫助在掃描時快速找到不同的部分,甚至為你提供一些內容以搜尋並直接跳轉到 CSS 的該部分。如果你使用一個不會出現在程式碼中的字串,你可以透過搜尋它來在各個部分之間跳轉——下面我們使用了||

css
/* || General styles */

/* … */

/* || Typography */

/* … */

/* || Header and Main Navigation */

/* … */

你不需要註釋 CSS 中的每一件事,因為其中很多都是不言而喻的。你應該註釋的是你在某個地方出於某種原因做出的決策。

例如,你可能以某種特定方式使用了 CSS 屬性來解決舊版瀏覽器的相容性問題。

css
.box {
  background-color: red; /* fallback for older browsers that don't support gradients */
  background-image: linear-gradient(to right, #ff0000, #aa0000);
}

也許你按照某個教程完成了某件事,並且 CSS 並不十分直觀或易於識別。在這種情況下,你可以將教程的 URL 新增到註釋中。當你在一年後回到這個專案並隱約記得有一個關於那個東西的精彩教程,但記不起它來自哪裡時,你會感謝自己。

在樣式表中建立邏輯部分

最好在樣式表中首先包含所有常用樣式。這意味著所有通常適用的樣式,除非你對該元素執行了特殊操作。你通常會為以下內容設定規則:

  • body
  • p
  • h1h2h3h4h5
  • ulol
  • table 屬性
  • 連結

在本節樣式表中,我們為網站上的文字提供了預設樣式,設定了資料表和列表的預設樣式等等。

css
/* || GENERAL STYLES */

body {
  /* … */
}

h1,
h2,
h3,
h4 {
  /* … */
}

ul {
  /* … */
}

blockquote {
  /* … */
}

在本節之後,我們可以定義一些實用程式類,例如,一個用於移除我們打算作為彈性專案或以其他方式顯示的列表的預設列表樣式的類。如果您有一些您知道需要應用於許多不同元素的樣式選擇,可以將它們放在此節中。

css
/* || UTILITIES */

.nobullets {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* … */

然後,我們可以新增網站範圍內使用的所有內容。這可能包括基本頁面佈局、頁首、導航樣式等。

css
/* || SITEWIDE */

.main-nav {
  /* … */
}

.logo {
  /* … */
}

最後,我們將包含特定內容的 CSS,並根據其使用上下文、頁面甚至元件進行細分。

css
/* || STORE PAGES */

.product-listing {
  /* … */
}

.product-box {
  /* … */
}

透過以這種方式排序,我們至少可以瞭解將在樣式表的那一部分中查詢我們要更改的內容。

避免過度具體的選取器

如果您建立非常具體的選取器,您會經常發現需要複製 CSS 的一部分才能將相同的規則應用於另一個元素。例如,您可能會有如下所示的選取器,它將規則應用於類名為 box<p> 元素,該元素位於類名為 main<article> 元素內。

css
article.main p.box {
  border: 1px solid #ccc;
}

如果您隨後想將相同的規則應用於 main 之外的元素或 <p> 以外的元素,則必須為這些規則新增另一個選取器或建立一個全新的規則集。相反,您可以使用選取器 .box 將您的規則應用於任何具有類 box 的元素。

css
.box {
  border: 1px solid #ccc;
}

有時使某些內容更具體是有意義的;但是,這通常是例外情況,而不是慣例。

將大型樣式表分解成多個較小的樣式表

在網站的不同部分具有非常不同的樣式的情況下,您可能希望有一個樣式表包含所有全域性規則,以及一些包含這些部分所需特定規則的較小樣式表。您可以從一個頁面連結到多個樣式表,並且級聯的正常規則適用,後面連結的樣式表中的規則位於前面連結的樣式表中的規則之後。

例如,我們可能在網站中有一個線上商店,其中許多 CSS 僅用於為產品列表和商店所需的表單設定樣式。將這些內容放在一個單獨的樣式表中,僅在商店頁面上鍊接,是有意義的。

這可以使您的 CSS 更易於組織,並且還意味著如果多人正在處理 CSS,您將遇到更少的兩種人需要同時處理同一個樣式表的情況,從而導致原始碼控制衝突。

其他可幫助你的工具

CSS 本身在內建組織方面並沒有太多內容;因此,CSS 中的一致性水平很大程度上取決於您。Web 社群開發了各種工具和方法來幫助您管理大型 CSS 專案。由於在與其他人合作時可能會遇到這些輔助工具,並且由於它們通常有幫助,因此我們提供了一些簡要指南。

CSS 方法

無需自己制定編寫 CSS 的規則,您可以從社群已經設計並在許多專案中測試過的方法中獲益。這些方法本質上是 CSS 編碼指南,採用非常結構化的方式來編寫和組織 CSS。通常,與您為該專案編寫和最佳化每個選取器以獲得自定義規則集相比,它們往往會使 CSS 變得更冗長。

但是,透過採用其中一種方法,您確實獲得了許多結構。由於許多這些系統被廣泛使用,因此其他開發人員更有可能理解您使用的方法並能夠以相同的方式編寫自己的 CSS,而不是必須從頭開始研究您自己的個人方法。

OOCSS

您將遇到的許多方法都或多或少地歸功於面向物件 CSS (OOCSS) 的概念,這是一種由 Nicole Sullivan 的工作 推廣的方法。OOCSS 的基本思想是將您的 CSS 分離成可重用的物件,這些物件可以在您網站的任何需要的地方使用。OOCSS 的標準示例是稱為 媒體物件 的模式。這是一種模式,一側是固定大小的影像、影片或其他元素,另一側是靈活的內容。這是我們在整個網站上看到的用於評論、列表等的模式。

如果您沒有采用 OOCSS 方法,則可能會為使用此模式的不同位置建立自定義 CSS,例如,透過建立兩個類,一個名為 comment,其中包含元件部分的一系列規則,另一個名為 list-item,其規則與 comment 類幾乎相同,除了某些細微差別。這兩個元件之間的區別在於列表項底部有邊框,評論中的影像有邊框,而列表項影像沒有。

css
.comment {
  display: grid;
  grid-template-columns: 1fr 3fr;
}

.comment img {
  border: 1px solid grey;
}

.comment .content {
  font-size: 0.8rem;
}

.list-item {
  display: grid;
  grid-template-columns: 1fr 3fr;
  border-bottom: 1px solid grey;
}

.list-item .content {
  font-size: 0.8rem;
}

在 OOCSS 中,您將建立一個名為 media 的模式,其中包含兩種模式的所有通用 CSS——用於通常具有媒體物件形狀的事物的基本類。然後,我們將新增一個額外的類來處理這些細微差別,從而以特定的方式擴充套件該樣式。

css
.media {
  display: grid;
  grid-template-columns: 1fr 3fr;
}

.media .content {
  font-size: 0.8rem;
}

.comment img {
  border: 1px solid grey;
}

.list-item {
  border-bottom: 1px solid grey;
}

在您的 HTML 中,評論需要同時應用 mediacomment 類。

html
<div class="media comment">
  <img src="" alt="" />
  <div class="content"></div>
</div>

列表項將應用 medialist-item

html
<ul>
  <li class="media list-item">
    <img src="" alt="" />
    <div class="content"></div>
  </li>
</ul>

Nicole Sullivan 在描述和推廣這種方法方面所做的工作意味著,即使是今天沒有嚴格遵循 OOCSS 方法的人通常也會以這種方式重用 CSS——它已經成為我們普遍理解的一種好的方法。

BEM

BEM 代表塊元素修改器。在 BEM 中,塊是一個獨立的實體,例如按鈕、選單或徽標。元素是諸如列表項或標題之類的與它所在的塊相關聯的內容。修飾符是塊或元素上的標誌,用於更改樣式或行為。您將能夠識別使用 BEM 的程式碼,因為 CSS 類中廣泛使用了破折號和下劃線。例如,檢視從關於 BEM 命名約定 的頁面應用於此 HTML 的類。

html
<form class="form form--theme-xmas form--simple">
  <label class="label form__label" for="inputId"></label>
  <input class="form__input" type="text" id="inputId" />

  <input
    class="form__submit form__submit--disabled"
    type="submit"
    value="Submit" />
</form>

其他類類似於 OOCSS 示例中使用的類;但是,它們使用 BEM 的嚴格命名約定。

BEM 在較大的 Web 專案中被廣泛使用,許多人以這種方式編寫 CSS。即使在教程中,您也可能會遇到使用 BEM 語法的示例,而沒有說明為什麼 CSS 以這種方式構建。

在 CSS Tricks 上閱讀有關此係統的更多資訊 BEM 101

其他常見系統

有大量此類系統正在使用。其他流行的方法包括由 Jonathan Snook 建立的 CSS 的可擴充套件和模組化架構 (SMACSS)、Harry Roberts 的 ITCSS 和最初由雅虎建立的 原子 CSS (ACSS)。如果您遇到使用其中一種方法的專案,那麼優勢在於您可以搜尋並找到許多文章和指南來幫助您瞭解如何以相同的風格進行編碼。

使用此類系統的缺點是它們可能看起來過於複雜,尤其是在較小的專案中。

CSS 構建系統

組織 CSS 的另一種方法是利用前端開發人員可用的某些工具,這些工具允許您採用稍微更具程式化的方法來編寫 CSS。有一些工具,我們稱之為預處理器後處理器。預處理器會遍歷您的原始檔案並將其轉換為樣式表,而後處理器會獲取您的完成樣式表並對其進行處理——也許是為了最佳化它以便更快載入。

使用任何這些工具都需要您的開發環境能夠執行執行預處理和後處理的指令碼。許多程式碼編輯器可以為您做到這一點,或者您可以安裝命令列工具來提供幫助。

最流行的預處理器是 Sass。這不是 Sass 教程,因此我將簡要解釋 Sass 可以執行的幾件事,這些事情在組織方面非常有用,即使您不使用任何其他 Sass 功能也是如此。如果您想了解有關 Sass 的更多資訊,請從 Sass 基礎 文章開始,然後繼續學習他們的其他文件。

定義變數

CSS 現在具有本機 自定義屬性,使此功能越來越不重要。但是,您可能使用 Sass 的原因之一是能夠將專案中使用的所有顏色和字型定義為設定,然後在整個專案中使用該變數。這意味著,如果您意識到使用了錯誤的藍色陰影,則只需在一個地方更改它即可。

如果我們建立一個名為 $base-color 的變數,如下面的第一行所示,那麼我們可以在需要該顏色的樣式表中的任何位置使用它。

scss
$base-color: #c6538c;

.alert {
  border: 1px solid $base-color;
}

編譯成 CSS 後,您將在最終樣式表中獲得以下 CSS。

css
.alert {
  border: 1px solid #c6538c;
}

編譯元件樣式表

我在上面提到過,組織 CSS 的一種方法是將樣式表分解成較小的樣式表。使用 Sass 時,您可以將其提升到另一個層次,並擁有許多非常小的樣式表——甚至可以為每個元件建立一個單獨的樣式表。透過使用 Sass 中包含的功能(部分),所有這些都可以編譯成一個或少量樣式表,以實際連結到您的網站。

因此,例如,使用 部分,您可以在目錄中擁有多個樣式檔案,例如 foundation/_code.scssfoundation/_lists.scssfoundation/_footer.scssfoundation/_links.scss 等。然後,您可以使用 Sass 的 @use 規則將它們載入到其他樣式表中。

scss
// foundation/_index.scss
@use "code";
@use "lists";
@use "footer";
@use "links";

如果所有部分都載入到索引檔案中(如上所述),則可以立即將整個目錄載入到另一個樣式表中。

scss
// style.scss
@use "foundation";

注意:嘗試使用 Sass 的一種簡單方法是使用 CodePen——您可以在 Pen 的設定中為您的 CSS 啟用 Sass,然後 CodePen 將為您執行 Sass 解析器,以便您可以看到應用了常規 CSS 的結果網頁。有時您會發現 CSS 教程在其 CodePen 演示中使用了 Sass 而不是純 CSS,因此瞭解一些關於 Sass 的知識非常方便。

最佳化後處理

如果您擔心向樣式表新增大小,例如,透過新增大量其他註釋和空格,那麼後處理步驟可能是透過刪除生產版本中任何不必要的內容來最佳化 CSS。執行此操作的後處理解決方案的一個示例是 cssnano

總結

這是我們的構建塊模組的最後一部分,如您所見,從這一點開始,您可以繼續探索 CSS 的許多方法——但現在您可以透過我們的評估來測試自己:第一個連結如下。

要了解有關 CSS 中佈局的更多資訊,請參閱 CSS 佈局 模組。

您現在還應該具備探索其餘 MDN CSS 材料的技能。您可以查詢屬性和值,探索我們的 CSS 食譜 以獲取要使用的模式,或者繼續閱讀一些特定指南,例如我們的 CSS 網格佈局指南