總結分享CSS設計模式知識點

2022-02-21 19:00:35
本篇文章給大家帶來了關於設計模式的相關知識,其中包括OOCSS、BEM、SMACSS、ITCSS以及ACSS的相關問題,希望對大家有幫助。

前言

傳統的CSS書寫風格是隨意命名,堆疊樣式,造成了混亂不堪的結果,你是否遇到龐大複雜的專案裡,CSS程式碼難以維護的情況,你是否想要除了能夠還原實物原型,而且程式碼規則有序極易維護。
那麼CSS設計模式就在實際應用中的拯救樣式混亂,程式碼行數冗餘的局面。這也是對一個專案設計CSS架構基礎。
啥?CSS還有設計模式!
沒錯兒,CSS真的有設計模式。

設計模式:OOCSS

OOCSS是比較基礎的設計模式,其他設計模式或多或少都有OOCSS的影子。那麼什麼是OOCSS呢?估計大家看到OO的時候就已經知道了,沒錯,就是是物件導向,那麼物件導向和我們寫CSS有半毛錢關係嗎?當然有。

OO:物件導向

大家都很熟悉物件導向,我們簡單看下下面這一段程式碼:

class Person {
    void study () {}
}

class Teacher extends Person {
    void study () {}
    void teach () {}
}

class Student extends Person {
    void study () {}
}

有一個Person類,它有一些方法,Teacher和Student都繼承Person,並且進行了一些修訂和擴充套件。那麼我們可以把Person類看成是別人寫程式碼,在不改變別人原始碼的情況下,新增Teacher和Student對原始碼進行修訂和擴充套件。這種寫法是完全可以應用到CSS上面的。我們看下面一段程式碼場景:

<p class="menu"></p>
<p class="menu fix"></p>
<p class="menu"></p>

.menu {
   color: green;
   font-size: 14px;
}

.fix {
   color: red;
}

場景:設計師只想讓我們改變其中一個盒子的樣式,其他的不變。
這時不能輕易改變menu,因為一旦改變就會影響不需要改變的地方。那麼我們可以直接利用物件導向的思想,在後面單獨新增一個類進行修訂和擴充套件。這樣一看我們平時在寫的CSS,不就是物件導向嗎?
當然,OOCSS是有具體的原則的。那麼它有哪些原則且個原則的具體是什麼呢?我們來看一下:

原則一:容器與內容分離

容器與內容分離顧名思義,直接看一個程式碼案例:

<p class="post"> 
  <p class="metadata">
    <a>Hello</a>
  </p>
</p>

<p class="comment"> 
  <p class="metadata">
    <a>Hello</a>
  </p>
</p>

// ---------code 1-----------
.post .metadata {
  // css code
}

// ---------code 2-----------
.post {}
.metadata {
  // css code
}

場景:兩個不同容器中的內容相同
先看樣式的code 1,這樣顯然不好,容器和內容是巢狀依賴關係,並沒有做到容器與內容分離。內容的樣式無法複用。樣式的code 2做到了容器與內容分離,內容在不同的容器中可以複用。

原則二:結構與面板分離

結構可以看做是一個基礎物件,而面板可以看做是另外一個物件,也就是物件與物件要分離。基礎物件不能改,不斷的分離出面板物件達到對基礎物件的修正和擴充套件。

<p class="menu fix"></p>

// 基礎物件
.menu {
  color: green;
  font-size: 14px;
}
// 面板
.fix {
  color: red;
}

OOCSS與Vue的關係

我們每天都在寫OOCSS,Vue的元件就是OOCSS。我們下面一段程式碼:

// -------------定義元件-----------------
<template>
  <p class="menu"></p>
</template>

<script>
  export default {
    name: 'MateData'
  }
</script>

<style> 
// 基礎物件
.menu {
   color: green;
   font-size: 14px;
}
</style>

// -----------使用元件-------------------

<template>
  <mate-data class="fix1"></mate-data>
  <mate-data class="fix2"></mate-data>
</template>

<style> 
// 面板
.fix1 {
   color: red;
}
.fix2 {
   font-size: 20px;
}
</style>

OOCSS的應用
Grid柵格系統、佈局元件等

設計模式:BEM

什麼是BEM

BEM即塊(Block)、元素(Element)、修飾符(Modifier) 是由Yandex(俄羅斯最著名的網際網路企業)的開發團隊提出的前端開發理論。BEM通過Block、Element、Modifier來描述頁面(關鍵就是為了解決多人共同作業的命名問題)。
Block是頁面中獨立存在的區塊,可以在不同場合下使用。每個頁面都可以看做是多個Block組成。
Element是構成Block的元素,只有在對應Block內部才具有意義,是依賴於Block的存在。
Modifier是描述Block或Element的屬性或狀態。同一Block或Element可以有多個Modifier,Modifier不可以單獨存在。
在命名時,Block作為起始開頭,不同 Block 和 Element 用 _ 兩個底線區隔開來,不同的 Modifier 則用 – 區隔。
在這裡插入圖片描述

進階版的OOCSS

BEM就是進階版的OOCSS,我們看下圖所示:
在這裡插入圖片描述
場景: 頁面兩個tab欄,整體佈局相似,只有細節部分不同
那麼使用BEM寫樣式時,就會定義一個塊menu,下面包含元素menu_tab,完成整體佈局,細微部分使用修飾符menu_tab-style1進行微調。程式碼如下:

<!-- BEM -->
<p class="menu menu-style1">
  <p class="menu_tab menu_tab-style1"></p>
  <p class="menu_tab menu_tab-style1"></p>
  <p class="menu_tab menu_tab-style1"></p>
  <p class="menu_tab menu_tab-style1"></p>
</p>

<p class="menu">
  <p class="menu_tab menu_tab-style2"></p>
  <p class="menu_tab menu_tab-style2"></p>
  <p class="menu_tab menu_tab-style2"></p>
  <p class="menu_tab menu_tab-style2"></p>
</p>

通過上面程式碼可以看出BEM就是OOCSS。
對BEM感興趣的話,可以存取BEM的官網: https://en.bem.info/methodology/css/
作用:
命名規範、讓頁面結構更清晰
另外關於命名規範使用的符號,團隊內部是可以討論修改的,不一定非要按照這種符號,BEM只是提供一個思想。

設計模式:SMACSS

SMACSS is a way to examine your design process and as a way to fit
those rigid frameworks into a flexible thought process.
(SMACSS通過一個靈活的思維過程來檢查你的設計過程和方式是否符合你的架構,更像一種規範~)

核心思想:分類

SMACSS的核心就是分類,它主要要求分為五大類分別是:Base、Layout、Modules、State、Theme

  • Base是對瀏覽器預設樣式的重置,常見的normalize.css就屬於此。這裡樣式只會對標籤元素本身做設定,不會出現任何 class 或id,但是可以有屬性選擇器或是偽類.
  • Layout對頁面佈局的一些功能,屬於較高的一層,它可以作為層級較低的Module Rules元素的容器。左右分欄、柵格系統等都屬於佈局規範。SMACSS還約定命名使用l-/layout-字首來標識佈局的class。
  • Modules公共複用的小模組,模組是SMACSS最基本的思想,同時也是大部分CSS理論的基本,將樣式模組化就能達到複用和可維護的目的,但是SMACSS提出了更具體的模組化方案。SMACSS中的模組具有自己的一個命名,隸屬於模組下的類皆以該模組為字首,例如:.menu .menu-title等。
  • State對不同的展示效果,例如顯示、隱藏,與BEM抽取修飾類的方式的不同,SMACSS是抽取更高階別的樣式類,得到更強的複用性,命名全都以is-字首,如:is-hidden。
  • Theme對不同主題面板的維護,可以修改前面4個類別的樣式,且應和前面4個類別分離開來(便於切換,也就是「換膚」)。命名規範需要新增theme-字首。

最小適配深度原則

/* depth 1 */
.sidebar ul h3 {}

/* depth 2 */
.sub-title {}

兩段css的區別在於html和css的耦合度(這一點上和OOCSS的分離容器和內容的原則不謀而合)。可以想到,由於上面的樣式規則使用了繼承選擇符,因此對於html的結構實際是有一定依賴的。如果html發生重構,就有可能不再具有這些樣式。對應的,下面的樣式規則只有一個選擇符,因此不依賴於特定html結構,只要為元素新增class,就可以獲得對應樣式。
當然,繼承選擇符是有用的,它可以減少因相同命名引發的樣式衝突(常發生於多人共同作業開發)。但是,我們不應過度使用,在不造成樣式衝突的允許範圍之內,儘可能使用短的、不限定html結構的選擇符。這就是SMACSS的最小化適配深度的意義。

在專案中使用SMACSS時,每一個分類都是一個目錄,但是在Vue中,Layout和Modules不需要單獨維護目錄,因為我們寫的佈局元件和模組元件就相當於這兩個分類了。

如果想要對SMACSS更詳細的瞭解可以存取:https://smacss-zh.vercel.app/preface.html

設計模式:ITCSS

這是由csswizardry提倡的一個 CSS 設計方法論,它可以讓CSS更好的管理和維護。
使用ITCSS主要可以幫助我們以下幾點:

  • Manages source order.
  • Filters explicitness.
  • Tames the cascade.
  • Sanitises inheritance.
    大概意思就是:
  • 管理 CSS 程式碼的書寫順序。
  • 過濾器的明確性,是說分層來明確每層 CSS 的作用。
  • 控制好 CSS 的權重
  • 安全地使用繼承

核心思想:分層

ITCSS的核心是分層,主要分為七層, 與SMACSS的分類相比更加精細,層
Settings: 專案使用的全域性變數
Tools: mixin,function
Generic: 最基本的設定 normalize.css,reset
Base: type selector
Objects: 不經過裝飾 (Cosmetic-free) 的設計模式,相當於SMACSS的Layout
Components: UI 元件
Trumps: helper 唯一可以使用 important! 的地方

下面就是ITCSS的架構模型:
在這裡插入圖片描述

從這個模型可以看出來,越往下就越具體,越侷限於使用在某個具體的東西。另外它的下一層永遠繼承上一層的所有樣式。
各個分層例子
Settings
全域性變數,比如顏色,字型大小等等

$yellow: #FAAF00;
$yellow-bright: #FAF7F0;

Tools
mixin,function 等等

@mixin sample-mixin () {
  ...
}

到 Tools 為止,不會生成具體的 css
Generic
reset,normalize 等等

*,
*::before,
*::after {
  box-sizing: border-box;
}

Base
type selector 比如 link, p 等等,只有這一層才使用 type selector

p {
  margin: 0
  line-height: 1.5;
}

Objects
Cosmetic-free,不使用比如 color、border-color、background-color 之類的
使用這個 CSS 你在瀏覽器上面只可以看一片空白
主要用來做畫面的 layout

.o-container {
  box-sizing: border-box;
  margin: 0 auto;
}

Components
UI 元件
到這個部分,根據UI分析具體有哪些元件需要實現,可以分給多個人來同時實現

#button元件

.c-btn {
  display: flex;
  justify-content: center;
  align-items: center;
  ...

  &--primary {
    background-color: #ff5959;
    color: #fff;
  }

  &--large {
    font-size: 16px;
    padding: 16px 14px;
    ...
  }
}

HTML 類似這樣

<a class="c-btn c-btn--primary" href="#">sample</a>
<a class="c-btn c-btn--primary c-btn--large" href="#">sample</a>

Trumps
放各種 helper
最主要的作用是用在不適合或者不容易放在 Component 的時候
比如 margin,很可能不應該放 Component,這時候可以用 Trumps 來微調
這樣可以防止你的 Component 變得非常大
只有這一層才可以使用! important,以此來避免多個! important 的混亂局面

.u-color {
  &--white {
    color: $white !important;
  }
}

.u-hidden {
  display: hidden !important;
 }

在使用時,每個分層都維護為一個資料夾。在Vue中使用時,Objects和Components相當於我們的元件,不需要單獨維護。
另外值得注意的是,無論是SMACSS的分類還是ITCSS的分層,都是一種思想,我們可以根據實際專案來動態的新增或者刪除某一個分類或者分層,不能生搬硬套。

設計模式:ACSS

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

.float-left {
  float: left;
}
.float-right {
  float: right;
}
.z-0 {
  z-index: 0;
}
.z-auto {
  z-index: auto;
}

從上面的程式碼中,可以看到ACSS有極強的複用性,維護成本低,但是破壞了css命名的語意化。最終很可能程式碼會成為下面這樣。但是存在即合理,ACSS也有其作用,繼續往下看。

<p class="grid grid-cols-3 gap-2 place-content-center h-48 ...">
  <p>1</p>
  <p>2</p>
  <p>3</p>
  <p>4</p>
  <p>5</p>
  <p>6</p>
</p>

混合使用CSS設計模式(CSS架構舉例)

在進行一個專案的設計時,我們可以針對多種CSS設計模式進行選型,結合不同設計模式的優點和缺點,設計一個完整銀杏的CSS架構。
舉例子::
假如我們選擇ITCSS、BEM、ACSS進行組合,設計一個CSS架構。
在我們設計CSS架構時,我們首先想到的一定是SMACSS和ITCSS,因為它們兩個對CSS進行了分類分層的劃分。
SMACSS:
Base
Layout
Tools
Modules
State
Theme
ITCSS:
Setting
Generic
Base
Objects
Components
Trumps

根據上表我們可以看出ITCSS分層更加精細,所以我們選擇ITCSS,接著我們繼續看ITCSS的Objects和Components層,它就相當於OOCSS且相當於開發Vue元件,所以我們在開發元件時使用選擇OOCSS的進階版BEM。我們知道如果一個專案全部使用ACSS的缺點跟明顯,那麼我們選擇ACSS的原因是因為專案中可能會存在向字型大小的這種的樣式,所以我們可以把這一類樣式維護在ACSS目錄中。Generic和Base類似所以只保留Base即可,我假設Trumps用不到,所以也去掉這一層。所以我們的架構現在就是下面這樣。
ITCSS+BEM+ACSS
Setting
Tools
Base
Objects
Components
ACSS

目錄結構就是:

-|comments
-|styles
--|acss
--|base
--|settings
--|tools

結束

講到這裡就該結束了,相信到這裡大家就發現了,CSS設計模式離我們真的很近,我們大家日常寫CSS時,所進行的優化和考量,也可以算成CSS的設計模式,可能沒有聯想到CSS設計模式這一概念。
我們平時寫程式碼時都會劃分一些資料夾對CSS進行分類維護,相信大家平時都見過和用過不少各種各樣的CSS架構或規範。
設計模式提供的是一個思想,在使用時,可以靈活變化,針對不同專案或者約定,進行商定調整,整出更加銀杏(人性)的CSS架構。也希望以上幾個CSS設計模式,能夠對大家有用。
碼字不易,點贊鼓勵。
謝謝大家。

(學習視訊分享:)

以上就是總結分享CSS設計模式知識點的詳細內容,更多請關注TW511.COM其它相關文章!