原文地址。本文從屬於Web 前端入門與最佳實踐。css
CSS的學習是一個典型的低門檻,高瓶頸的過程,第一次接觸CSS的時候以爲一切是如此簡單,直到後面越學愈加現本身一無所知,建議看看張鑫旭老師的說說CSS學習中的瓶頸。本文則是從四個方面來討論如何編寫可擴展、可維護的CSS代碼:html
使用合理的語義化命名前端
模塊化git
遵循命名規範github
遵循單一職責原則sass
在HTML與CSS中都存在着語義化標記的概念,Semantics便是單次的語義和其關聯,在HTML中一個簡單的示意以下:app
<!-- bad --> <div class=」footer」></div> <!-- good --> <footer></footer>
語義化的HTML可以比較直接的表示出某個標記的功能,另外一方面,Semantic CSS會更加地抽象與主觀化。編寫語義化地CSS代碼意味着你選定的樣式類名要可以簡單明瞭的反映出結構與功能信息。另外一方面,樣式類命名的時候能夠不用太過具體化,這樣也方便你複用樣式類。模塊化
這裏咱們以Medium的CSS進行一個說明:wordpress
<div class="stream"> <div class="streamItem"> <article class="postArticle"> <div class="postArticle-content"> <!-- content --> </div> </article> </div> </div>
從上述代碼中,你能夠迅速辨別出結構、角色和含義。父類爲stream
,表明着一系列文章的列表。而第一個子類爲streamItem
,即列表中的某個文章的實體,這就明顯表現出了子類與父類之間的從屬關係。另外,這樣一個類與結構能夠在任何包含文章的頁面上完成複用。對於可讀性較好地HTML與CSS代碼,不該該像一本書,而應該像一個故事,一個故事中會存在角色和角色之間的關係,而這種更多的語義化地CSS能夠較好地提示你整個代碼的可維護性。下面推薦幾個深刻閱讀的文章:post
[About HTML semantics and front-end architecture](
http://nicolasgallagher.com/a...
在像React這樣的基於組件的項目中,模塊化就是根本地準則。經過建立可複用可組合的模塊能夠將整個系統合理解耦。
上圖中每一個藍色塊內就表明一個組件:
<div class="stream"> <div class="streamItem"> <!-- product info --> </div> </div>
大部分的組件又能夠拆分爲更多的小組件:
每一個Stream Item都含有一個縮略圖和特徵信息:
<!-- STREAM COMPONENT --> <div class="stream"> <div class="streamItem"> <!-- POST COMPONENT --> <div class="post"> <img src="thumbnail.png" class="postThumbnail"/> <div class="content"> <!-- product info --> </div> </div> </div> </div>
由於stream組件不依賴於其子組件,所以能夠隨意地修改post類而不會對stream類有明顯地影響。通常來講,代碼之間的耦合程度越低,代碼的可修改性與可維護性就越好。
深刻閱讀:
目前已經有了不少的優秀的CSS命名約定規範,不過最好的CSS命名規範仍是最適合本身的,所以筆者本身的感受就是選一個最順眼的命名約定而後將它改形成適合本身的項目的規範。
我我的最喜歡的一個命名規範就是BEM:
BEM是最簡單,不過也是最嚴格的命名規範:
.block {} .block__element {} .block--modifier {}
上述代碼中的Blocks表明了高等級的一些類,Elements則是Blocks的子元素,而Modifiers表明了不一樣的狀態。
<div class="search"> <input type="search__btn search__btn--active" /> </div>
在上述例子中,search類是一個Block,而Search Button則是它的一個子元素,若是你但願修改按鈕的狀態,那麼應該添加一個相似於active的Modifier。另外你須要記住的是,將來你工做的代碼庫裏頗有可能會出現多個命名規範,你也要學會兼容幷包,可以接受學習其餘的一些標準。若是你但願對於BEM進行深刻了解,那麼能夠閱讀如下文章:
SRP原則即只每一個模塊或者類只應承擔軟件系統中的某個單一功能,而且該職責應該完整地封裝在類的內部,即對外屏蔽內部實現。而具體到CSS的領域裏,SRP意味着某個代碼片、類或者模塊只應該作一件事。而在CSS的文件組織上,意味着像Carousels、Navigation Bar這樣的組件應該有本身獨立的CSS文件。
/components |- carousel |- |- carousel.css |- |- carousel.partial.html |- |- carousel.js |- nav |- |- nav.css |- |- nav.partial.html |- |- nav.js
另外一個常見的文件組織方式就是按照功能進行文件組織,舉例而言,在上述的代碼片中,全部關於Carousel的文件都應該被放到同一個文件夾中。經過這種方式能夠將文件索引變得更加容易。一樣地,對於常見的全局樣式而言,也須要適用於獨立地全局樣式:
/base |- application.css |- typography.css |- colors.css |- grid.css
在上述例子裏,不一樣類型的全局樣式須要分割到不一樣的文件中,這樣的話若是你須要去更改你的顏色等等樣式,那就很容易找到修改哪一個文件。不管哪一種文件組織方式比較順眼,你都應該遵循統一的SRP原則。若是某個文件變得冗餘臃腫,你應該考慮根據邏輯或者其餘東西對內容進行切分。關於文件組織結構與CSS結構方面地深刻閱讀:
對於每一個獨立的CSS類而言,都應該只包含一個功能。換言之,應該根據關注點的差別將樣式切分到不一樣的類中,這裏有個小例子:
.splash { background: #f2f2f2; color: #fffff; margin: 20px; padding: 30px; border-radius: 4px; position: absolute; top: 0; right: 0; bottom: 0; left: 0; }
在上面這個例子裏,咱們搞錯了某些關注點,splash
類不只包含了其本身的展現的樣式與邏輯,還定義了部分關於其子元素的樣式,所以須要切分到兩個單獨類中:
.splash { position: absolute; top: 0; right: 0; bottom: 0; left: 0; }
.splash__content { background: #f2f2f2; color: #fffff; padding: 30px; border-radius: 4px; }
深刻閱讀: