CSS設計模式介紹

孫凱亮發表於2021-05-27

一、 常見CSS設計模式分析

oocss

Object Oriented CSS,物件導向的CSS,旨在編寫高可複用、低耦合和高擴充套件的CSS程式碼。

OOCSS是以物件導向的思想去定義樣式,將抽象(結構)和實現(樣式)分離,抽離公共程式碼。

區分結構和樣式
在定義一個可重用性的元件庫時,我們僅建立基礎的結構(html)和基礎的類名,不應該建立類似於border, width, height, background等樣式規則,這樣使元件庫更靈活和可擴充套件性。元件庫在不同環境下的樣式所要求不一樣,若未能區分其結構和樣式,給其新增樣式,會使其變成一個特定的元件庫,而難以重用。

以下是一個基礎庫建立的樣式:

.metadata{
  font-size: 1.2em;
  text-align: left;
  margin: 10px 0;
}

若在給其新增更多的樣式:

.metadata{
    font-size: 1.2em;
    text-align: left;
    margin: 10px 0;
    /*在基礎元件上新加的樣式*/
    width: 500px;
    background-color: #efefef;
    color: #fff;
}

這樣就使前面建立的基礎元件metadata變成了一個特定的元件了,使其在其他場景下較難複用。

區分容器和內容, 把容器和內容獨立分割槽,使內容能作用於任何容器下。

#sidebar h3 {
  font-family: Arial, Helvetica, sans-serif;
  font-size: .8em;
  line-height: 1;
  color: #777;
  text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
}

上面我們定義了一個id為sidebar 中 h3的樣式,但是我們發現在footer 中 h3的樣式也基本一致,僅個別不一樣,那麼我們可能會這樣寫樣式:

#sidebar h3, #footer h3 {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 2em;
  line-height: 1;
  color: #777;
  text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
}

#footer h3 {
  font-size: 1.5em;
  text-shadow: rgba(0, 0, 0, .3) 2px 2px 4px;
}

甚至我們可能會用更糟糕的方式來寫這個樣式:

#sidebar h3 {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 2em;
  line-height: 1;
  color: #777;
  text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
}

#footer h3 {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 1.5em;
  line-height: 1;
  color: #777;
  text-shadow: rgba(0, 0, 0, .3) 2px 2px 4px;
}

我們可以看到上面的程式碼中出現了不必要的duplicating styles。而OOCSS鼓勵我們應該思考在不同元素中哪些樣式是通用的,然後將這些通用的樣式從模組、元件、物件等中抽離出來,使其能在任何地方能夠複用,而不依賴於某個特定的容器。

<div class="header theme"></div>
<div class="footer theme"></div>
.header {
  height: 100px;
  width: 100px;
}

.footer {
  height: 200px;
  width: 100px;
}

.theme {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 2em;
  line-height: 1;
  color: #777;
  text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
}

最終實現結構與樣式分離,從而提高了樣式程式碼的可複用性

SMACSS

image.png

Scalable and Modular Architecture for CSS,可擴充套件模組化的CSS,它的核心就是結構化CSS程式碼,提出了一種CSS分類規則,分為五種型別:

  • Base

  • Layout

  • Module

  • State

  • Theme

SMACSS定義了一種css檔案的組織方式,其橫向的切分,即按照功能模組劃分,使css檔案更具有結構化、高可維護性。

  1. Base

Base是預設的樣式,是對單個元素選擇器(包括其屬性選擇器,偽類選擇器,孩子/兄弟選擇器)的基礎樣式設定,例如html, body, input[type=text], a:hover, etc.

html, body {
  margin: 0;
  padding: 0;
}

input[type=text] {
  border: 1px solid #999;
}

a {
  color: #039;
}

a:hover {
  color: #03C;
}

CSS Reset/Normalize就是一種Base Rule的應用.

Note: 在基礎樣式中不應該使用!important

  1. Layout

不明思議,是對頁面佈局元素(頁面架構中主要和次要的元件)的樣式設定,例如header, navigation, footer, sidebar, login-form, etc.


.header, footer {
  margin: 0;
}

.header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 9999;
}

.navs {
  display: inline-block;
  margin: 0 auto;
}
  1. Modules

對公共元件樣式的設定,例如dropdown, tabs, carousels, dialogs, etc.


.dropdown, .dropdown > ul {
  display: inline-block;
  border: 1px solid #283AE2;
}

.dropdown li:hover {
  background-color: #999;
}

.tabs {
  border: 1px solid #e8e8e8;
}

.tabs > .tab--active {
  border-bottom: none;
  color: #29A288;
}
  1. State

對元件、模組、元素等表現行為或狀態的樣式修飾,例如hide, show, is-error, etc.


.hide {
  display: none;
}

.show {
  display: block;
}

.is-error {
  color: red;
}
  1. Theme

對頁面整體佈局樣式的設定,可以說是一種皮膚,它可以在特定場景下覆蓋base, layout等的預設樣式。


.body--theme-sky {
  background: blue url(/static/img/body--theme-sky.png) repeat;
}

.footer--theme-sky {
  background-image: blue url('/static/img/header--theme-sky.png') no-repeat center;
}

BEM

BEM 是我的方法的基礎。如果你以前從未聽說過 BEM,它代表 block , element 和 modifier。當你第一次接觸它時,它看起來是那麼的難看。

.block { /* styles */ } 
.block__element { /* styles */ } 
.block--modifier { /* styles */ }

當我第一次看見 BEM 的時候,我就很討厭它,甚至沒有給它一個機會。我不記得是什麼驅使我嘗試 BEM 的,但我現在深深的知道它有多麼的強大。讓我來完整地解釋一下 BEM 是什麼(當然,加入了我自己的理解)。

一個塊就是一個元件。這有點抽象,所以讓我們用示例來學習。

假設您正在建立一個聯絡表單。在這種情況下,這個表單可以是一個塊。在 BEM 中,塊被寫為像 class 的名字一樣,如下所示:

.form { /* styles */ }

BEM 使用 .form 而不是 <form> 元素的原因是因為 類允許無限的可重用性,而即使是最基本的元素也可能改變樣式。

按鈕很好地闡釋了可以包含不同樣式的塊。如果將 <button> 元素的背景顏色設定為紅色,則所有<buttons> 都將被強制繼承紅色背景。接下來,你必須通過覆蓋你的<button> 元素來修復程式碼(並且可能會在修復中“傷及無辜” )。

button { 
    background-color: red; 
} 

.something button { 
    background-color: blue;
}

如果設定了一個 .button 類的按鈕,則可以在任何<button>元素上選擇是否使用 .button 類。那麼,如果你需要一個不同的背景顏色,你所做的就是改成一個新的 class,比如說 .button--secondary,很舒服吧!

.button { 
    background-color: red; 
}

.button--secondary { 
    background-color: blue;
}
  1. 元素

元素是塊的子節點。為了表明某個東西是一個元素,你需要在塊名後新增__element。所以,如果你看到一個像那樣的名字,比如 form__row ,你將立即知道 .form 塊中有一個 row 元素。

<form class="form" action=""> 
    <div class="form__row"> 
        <!-- ... --> 
    </div> 
</form>

.form__row { 
    /* styles */ 
}

BEM 元素有兩個優點 :

  • 你可以讓 CSS 的優先順序保持相對扁平。
  • 你能立即知道哪些東西是一個子元素。

為了解釋以上兩點,考慮使用兩個單獨的 class 的替代方法(許多框架這麼做的)。你可能會用這樣的東西:

<form class="form" action=""> 
    <div class="row"> 
        <!-- ... --> 
    </div>
</form> 

.form .row { 
    /* styles */ 
}

如果你使用 BEM 元素,則可以使用優先順序為 10 而不是 20 的的選擇器來為 .form__row 提供樣式。此外,你可以立即分辨出(不論是在 HTML 還是 CSS 中).form__row.form的子節點。

  1. 修飾符

修飾符是改變某個塊的外觀的標誌。要使用修飾符,可以將 --modifier 新增到塊中。

從上面的按鈕示例繼續,修改的按鈕將被命名為 .button--secondary。

在傳統的 BEM 中,當你使用修飾符時,你應該 將塊和修飾符新增 到 HTML 中,以便在新的 .button--secondary 中不重寫 .button 樣式。

<button class="button">Primary button</button>
<button class="button button--secondary">Secondary button</button>

.button { 
    padding: 0.5em 0.75em; 
    background-color: red; 
} 
.button--secondary { 
    background-color: green; 
}

注意為什麼沒有必要在 .button--secondary 中重新宣告 padding,因為它已經在 .button 中宣告瞭。這很棒,因為 BEM 確保你編寫簡潔的 CSS,而不需要付出大量的工作。

ITCSS

組織CSS的現代方法通常會退回到模組化或CSS物件來構造抽象思想。

倒三角形CSS的新思想是一種基於 CSS屬性 的特異性和重要性的分層方法 。 與SMACSS和OOCSS相比,這是一種鮮為人知的方法-儘管兩者都可以與ITCSS結合使用。

由於ITCSS 主要是專有的 ,因此不存在有關其用法的詳細規則手冊。 我們只能使用一組特定的原則 。 作者在下面的視訊中談到了它們。

預設情況下,ITCSS使用相同的原則OOCSS 但基於特異性更大的分離 。 因此,如果您已經熟悉OOCSS,請考慮嘗試使用這種獨特的替代CSS體系結構 。

以下是使用ITCSS的最大好處:

  • 頁面物件可以拆分為自己CSS / SCSS檔案,以實現可重用性 。
  • 複製/貼上並將每個物件擴充套件到其他專案很簡單 。
  • 具體的深度取決於您 。
  • 沒有設定的資料夾結構 ,也不需要使用預處理工具。
  • 您可以合併來自其他方法(例如CSS模組)的概念,以建立自己的混合工作流 。

image.png

從倒三角形的平坦頂部到底部尖端的定向流表示特異性的增加 。 由於專注於降低特異性 ,因此可以更輕鬆地在站點中多次重用類。

三角形的每個子部分都可以視為一個單獨的檔案或檔案組,儘管您無需以這種方式編寫程式碼。 由於具有匯入功能,因此對Sass / Less使用者更有意義。 只需將每個小節視為拆分和組織可重用CSS程式碼的方法即可 。

讓我們快速看一下倒三角形從上到下的每個部分 。

  • 設定 –預處理程式變數和方法(無實際CSS輸出)
  • 工具 – Mixins和函式(無實際CSS輸出)
  • 常規 – CSS重置,其中可能包括Eric Meyer的重置, Normalize.css或您自己的一批程式碼
  • 元素 –沒有類的單個HTML元素選擇器
  • 物件 -通常遵循OOCSS方法的頁面結構類
  • 元件 –用於設定任何頁面元素和所有頁面元素樣式的美學類(通常與物件類的結構結合使用)
  • Trumps –最重要的樣式,用於覆蓋三角形中的任何其他內容

倒三角形的每一層都可以調整以滿足您的需要 。 因此,如果您不使用CSS前處理器,則不需要設定或工具層。

在實際專案中應當靈活使用。

ACSS

ACSS使用了緊密的類名庫。 這些類名通常被縮寫,並與它們影響的內容分開。 在ACSS系統中,您可以知道類名的作用; 但是類名稱(至少不是樣式表中使用的名稱)與內容型別之間沒有關係,即每一個樣式對應一個類,也稱原子類CSS。

.bg-a {
  background-color: #a6d5fa;
}
.bg-b {
  background-color: #aedbaf;
}
.bg-c {
  background-color: #ffe8a5;
}
.bg-d {
  background-color: #faaaa4;
}

二、CSS設計模式在UI庫中的使用情況分析

  1. Element UI

    ITCSS + BEM

  2. Ant Design

    ITCSS + BEM

  3. Bootstrap

    ITCSS + OOCSS

  4. Tailwind CSS

    ACSS

總結

  • 在各流行UI庫中CSS設計模式無處不在
  • 我們應當積極在專案中實現自己的CSS設計模式組合以便優化我們專案的CSS架構
  • 建議使用ITCSS架構,配合BEM命名規範,組織ACSS基礎樣式便於後續使用

相關文章