前端體系的變化可謂是日新月異,短短一年時間,從理論、框架、構建工具、甚至開發語言都發生非常大的變化。 隨著新項目就即將啟動,我抽時間回顧了一下以往項目的前端架構,零零散散產生了許多想法,儘量一一記錄下來,為新的框架搭建做點準備。 首先來聊聊CSS的的各種規範與理論。回顧過去的代碼,首先讓我頭痛不已的 ...
前端體系的變化可謂是日新月異,短短一年時間,從理論、框架、構建工具、甚至開發語言都發生非常大的變化。 隨著新項目就即將啟動,我抽時間回顧了一下以往項目的前端架構,零零散散產生了許多想法,儘量一一記錄下來,為新的框架搭建做點準備。
首先來聊聊CSS的的各種規範與理論。回顧過去的代碼,首先讓我頭痛不已的就是那些不知所謂的類名,以及數不清的難以維護的CSS/LESS代碼。
我曾經對自己和前端小組的成員提出過要求,強制使用BEM方法來書寫CSS,但是在使用的過程中,也出現了總總問題。
它帶來的好處是顯而易見的,每個元素都被清晰描述出來,這也非常符合自文檔化代碼的要求。但同時也引發很多諸多問題
- 單純使用BEM方法,並沒有很好的去構建CSS的結構
- 複雜的業務邏輯帶來複雜的頁面,導致複雜的類名。
- 組件的嵌套以及組件狀態使得一個元素上應用大量的類,這讓第二個問題更加嚴重
在這個過程中,我們開始鬆懈了要求,這使得我們的CSS代碼又回到了混亂無序的原始時代。
因此我想我必須去重新去探究CSS的各種規範與理論。
一、OOCSS(面向對象的CSS)
OOCSS有兩個主要的原則:分離結構和外觀,以及分離容器和內容。
與任何基於對象的編程方法一樣,OOCSS 的目的是鼓勵代碼復用,使得最終的樣式可以更快地和更有效地添加和維護。
OOCSS風格的CSS也可以描述為兩點:增加class、不使用繼承選擇符。
<div class="box simple"> <div class="box-content active"> <p class="box-title">OOCSS</p> </div> </div>
上面這段代碼是一段遵循OOCSS模式的代碼
-
- 其中"normal"作為外觀和結構分離,例如"simple"可用使用的是直角,我將"simple"換成"complex",就"box"變成了圓角。
- 分離容器和內容,是指不再將元素位置作為樣式的限定詞,比如"box-title"就是文本的樣式,無論這個類作用在哪裡,都會是相同的樣式呈現。
OOCSS的缺點
-
- OOCSS適合真正的大型網站開發,因為大型網站用到的可重用性組件特別的多,如果運用在小型項目中可能見不到什麼成效。所以用不用OOCSS應該根據你的項目來決定。
- 如果沒用巧妙的使用,創建組件可能對於你來說是一堆沒用的東西,成為一爛攤子,給你的維護帶來意想不到的杯具,說不定還是個維護的噩夢。
- 最好給每一個組件備寫一份說明文檔,有助於調用與維護
二、SMACSS(模塊化架構可擴展CSS)
我們把上面的代碼用SMACSS風格來再次寫出來
<div class="box box-simple"> <div class="box-content is-active"> <p class="box-title">SMACSS</p> </div> </div>
儘管SMACSS和OOCSS有許多相似之處。但不同點是它把樣式系統劃分為五個具體類別。
-
- 基礎
- 如果不添加CSS類名,標記會以什麼外觀呈現
- 例如瀏覽器的 reset 可以寫在這裡
html {} input[type=text] {} a:hover {}
- 佈局
- 把頁面分成一些區域,是指整個網站的「大架構」的外觀,而非
button
這種小元件的 class - 通常只有一個選擇器,一個 id、或一個 class。
.header {} .articles {} .sidebar {}
- 把頁面分成一些區域,是指整個網站的「大架構」的外觀,而非
- 模塊
- 設計中的模塊化、可復用單元,就如同代碼中的"box-title"一樣,無論這個類作用在哪裡,都會是相同的樣式呈現
- 狀態
- 描述在特定狀態或情況下的顯示方式,代碼中的“is-active”就是一個狀態類
- 主題
- 一個可選的視覺外觀層,可以讓你更換不同主題
- 主題可以修改前面4個類別的樣式,且應和前面4個類別分離開來(便於切換,也就是“換膚”)。
- SMACSS的Theme Rules不要求使用單獨的class命名,也就是說,你可以在佈局中定義.header{ },然後在主題中也用.header { }來定義需要修改的部分來覆蓋前面的樣式
- 基礎
三、BEM(塊元素修飾符)
同樣的,使用BEM風格,重寫上面的代碼
<div class="box box--simple"> <div class="box__content box__content--active"> <p class="box__title">BEM</p> </div> </div>
BEM是一個CSS命名的命名規則,它不涉及如何書寫CSS的結構,只是建議每個元素都添加帶有如下內容的CSS類名
-
- 塊名
所屬組件的名稱
-
- 元素
元素在塊裡面的名稱
-
- 修飾符
任何與塊或元素相關聯的修飾符
BEM模式下,看起來很累贅、很冗餘,但是每一個CSS類名都很好的描述了它的作用,在結合LESS或者SASS使用時,會使它的書寫複雜程度降低。
四、規則文檔
我們往往會非常註重大的方法,而忘記細節,而一份完善的規則文檔會時刻提醒我們按照要求書寫代碼
一份好的規則文檔,應該遵循以下規範:
-
- 中包含不可變的規則,而不是籠統的說明
- 總是把規則提煉成最簡單的表達
- 總是首先說明規則 是什麼,再說明“如果不這樣,那麼會如何”
- 每個規則必須包含以下詞中的一個——總是、永遠不要、只有、每一個、不要、要
五、綜合方案
就像開篇所說一樣,單純的使用BEM並沒有很好的解決我們在項目中所遇到能再的問題,反而產生了新的問題。
但這並不是BEM的責任,CSS作為前端架構的重要一環,我們必須要針對項目來選擇一個合適的解決方案,而不是因為業界流行就去使用它。
往往單一的理論是無法支撐起真實需求的,因此,我們必須結合現有的方法來制定一個新的方案。比如繼續堅持BEM風格以及js hook,同時引入SMACSS、OOCSS亦或者其他方法,並且用一份嚴格的規則文檔來規範整個項目的細節。
如果喜歡我的文章,可以掃描二維碼關註我的微信公眾號
爭取每天都分享一點我自己的開發和練習體驗~