一、 常見CSS設計模式分析

oocss

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

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

區分結構和樣式

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

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

  1. .metadata{
  2. font-size: 1.2em;
  3. text-align: left;
  4. margin: 10px 0;
  5. }
  6. 若在給其新增更多的樣式:
  7. .metadata{
  8. font-size: 1.2em;
  9. text-align: left;
  10. margin: 10px 0;
  11. /*在基礎元件上新加的樣式*/
  12. width: 500px;
  13. background-color: #efefef;
  14. color: #fff;
  15. }

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

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

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

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

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

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

  1. #sidebar h3 {
  2. font-family: Arial, Helvetica, sans-serif;
  3. font-size: 2em;
  4. line-height: 1;
  5. color: #777;
  6. text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
  7. }
  8. #footer h3 {
  9. font-family: Arial, Helvetica, sans-serif;
  10. font-size: 1.5em;
  11. line-height: 1;
  12. color: #777;
  13. text-shadow: rgba(0, 0, 0, .3) 2px 2px 4px;
  14. }

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

  1. <div class="header theme"></div>
  2. <div class="footer theme"></div>
  3. .header {
  4. height: 100px;
  5. width: 100px;
  6. }
  7. .footer {
  8. height: 200px;
  9. width: 100px;
  10. }
  11. .theme {
  12. font-family: Arial, Helvetica, sans-serif;
  13. font-size: 2em;
  14. line-height: 1;
  15. color: #777;
  16. text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
  17. }

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

SMACSS

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.

  1. html, body {
  2. margin: 0;
  3. padding: 0;
  4. }
  5. input[type=text] {
  6. border: 1px solid #999;
  7. }
  8. a {
  9. color: #039;
  10. }
  11. a:hover {
  12. color: #03C;
  13. }

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

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

  1. Layout

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


  1. .header, footer {
  2. margin: 0;
  3. }
  4. .header {
  5. position: fixed;
  6. top: 0;
  7. left: 0;
  8. right: 0;
  9. z-index: 9999;
  10. }
  11. .navs {
  12. display: inline-block;
  13. margin: 0 auto;
  14. }
  1. Modules

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


  1. .dropdown, .dropdown > ul {
  2. display: inline-block;
  3. border: 1px solid #283AE2;
  4. }
  5. .dropdown li:hover {
  6. background-color: #999;
  7. }
  8. .tabs {
  9. border: 1px solid #e8e8e8;
  10. }
  11. .tabs > .tab--active {
  12. border-bottom: none;
  13. color: #29A288;
  14. }
  1. State

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


  1. .hide {
  2. display: none;
  3. }
  4. .show {
  5. display: block;
  6. }
  7. .is-error {
  8. color: red;
  9. }
  1. Theme

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


  1. .body--theme-sky {
  2. background: blue url(/static/img/body--theme-sky.png) repeat;
  3. }
  4. .footer--theme-sky {
  5. background-image: blue url('/static/img/header--theme-sky.png') no-repeat center;
  6. }

BEM

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

  1. .block { /* styles */ }
  2. .block__element { /* styles */ }
  3. .block--modifier { /* styles */ }

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

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

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

  1. .form { /* styles */ }

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

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

  1. button {
  2. background-color: red;
  3. }
  4. .something button {
  5. background-color: blue;
  6. }

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

  1. .button {
  2. background-color: red;
  3. }
  4. .button--secondary {
  5. background-color: blue;
  6. }
  1. 元素

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

  1. <form class="form" action="">
  2. <div class="form__row">
  3. <!-- ... -->
  4. </div>
  5. </form>
  6. .form__row {
  7. /* styles */
  8. }

BEM 元素有兩個優點 :

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

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

  1. <form class="form" action="">
  2. <div class="row">
  3. <!-- ... -->
  4. </div>
  5. </form>
  6. .form .row {
  7. /* styles */
  8. }

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

  1. 修飾符

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

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

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

  1. <button class="button">Primary button</button>
  2. <button class="button button--secondary">Secondary button</button>
  3. .button {
  4. padding: 0.5em 0.75em;
  5. background-color: red;
  6. }
  7. .button--secondary {
  8. background-color: green;
  9. }

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

ITCSS

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

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

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

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

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

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

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

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

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

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

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

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

ACSS

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

  1. .bg-a {
  2. background-color: #a6d5fa;
  3. }
  4. .bg-b {
  5. background-color: #aedbaf;
  6. }
  7. .bg-c {
  8. background-color: #ffe8a5;
  9. }
  10. .bg-d {
  11. background-color: #faaaa4;
  12. }

二、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基礎樣式便於後續使用