一、 常見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
Scalable and Modular Architecture for CSS,可擴充套件模組化的CSS,它的核心就是結構化CSS程式碼,提出了一種CSS分類規則,分為五種型別:
-
Base
-
Layout
-
Module
-
State
-
Theme
SMACSS定義了一種css檔案的組織方式,其橫向的切分,即按照功能模組劃分,使css檔案更具有結構化、高可維護性。
- 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
- 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;
}
- 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;
}
- State
對元件、模組、元素等表現行為或狀態的樣式修飾,例如hide, show, is-error, etc.
.hide {
display: none;
}
.show {
display: block;
}
.is-error {
color: red;
}
- 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;
}
- 元素
元素是塊的子節點。為了表明某個東西是一個元素,你需要在塊名後新增__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
的子節點。
- 修飾符
修飾符是改變某個塊的外觀的標誌。要使用修飾符,可以將 --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模組)的概念,以建立自己的混合工作流 。
從倒三角形的平坦頂部到底部尖端的定向流表示特異性的增加 。 由於專注於降低特異性 ,因此可以更輕鬆地在站點中多次重用類。
三角形的每個子部分都可以視為一個單獨的檔案或檔案組,儘管您無需以這種方式編寫程式碼。 由於具有匯入功能,因此對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庫中的使用情況分析
-
ITCSS + BEM
-
ITCSS + BEM
-
ITCSS + OOCSS
-
ACSS
總結
- 在各流行UI庫中CSS設計模式無處不在
- 我們應當積極在專案中實現自己的CSS設計模式組合以便優化我們專案的CSS架構
- 建議使用ITCSS架構,配合BEM命名規範,組織ACSS基礎樣式便於後續使用