你有沒有在一個逐漸膨脹的 CSS 項目中感到混亂呢?保持樣式風格統一和 HTML 的影響是比較困難的:儘管修改一個較小的問題,均可能建立更多醜陋的 hack,也可能 CSS 的小改變會影響 JavaScript 的功能。可是這些問題能在咱們的項目開始的時候靜心規劃,就能很大程度上避免這些問題。讓咱們開始說 CSS 架構吧。css
一個好的 CSS 架構是具備良好的可擴展性。可擴展性是在任何項目開發中都是具備挑戰性的,範圍的擴大或者團隊人數的增長,這些挑戰在 CSS 中也不例外。層級和全局的特性使 CSS 很強大,反之在開發過程當中也是脆弱的。若是你寫了一段時間 CSS,你會發現當改變一行 CSS 來修復一個功能的時候會破壞一批其餘的 CSS 功能,這將讓你很頭痛。細心的規劃能提供下列的好處:html
更少的樣式git
更少的樣式衝突github
更長的維護週期web
更快的提高新團隊成員vim
團隊成員之間更容易交流瀏覽器
更平穩的項目交接sass
Jonathan Snook 對 CSS 規則進行分類的概念在他的書中很受歡迎 Scalable and Modular Architecture for CSS-可擴展的模塊化 CSS 架構(SMACSS)。咱們的結構按下面的類型進行分類可以幫助咱們以及咱們的團隊更好的理解每個樣式的用途。我使用 7 種分類來定義規則集合,大多數是基於 SMACSS 推薦的作法,確保每個風格都適合這些類別之一。架構
基本樣式 (Base Styles)app
對象 (Objects)
組件 (Components)
狀態 (State)
主題 (Themes)
工具集 (Utilities)
JavaScript 勾子 (JavaScript hooks)
理解這些分類和目的,將有助於你寫出更高抽象層次的樣式。
基本樣式規則是建立在元素上。他們是你的網站想設置的全局默認樣式。典型的,包括像:排版、box-sizing、你可能想統一全部瀏覽器元素的正常值。一個常見的錯誤,你並不想要過重的基本元素風格,並建立默認值。你真的想移除無序列表的標準強調樣式或者只是在某些狀況下移除它?
對象規則只關注結構和佈局。不被容許修飾類的樣式。對象類的概念是 Nicole Sullivan 推廣的,爲了重用相同結構和佈局的頁面模式。在你的設計中尋找頁面結構的模式,並建立能夠在網站的多個組件或部分使用的對象類。經過把這些樣式映射爲對象類,你就可能避免冗餘,減小你的CSS的大小。網格系統,不管是手工編寫的或採用的一個框架,都適合使用對象類型。
組件是分離的、自成一體的 UI 零件。他們是麪包和黃油的原子設計,將組成你的大多數樣式。一個組件能小到一個按鈕,或大到一個切換。建立魯棒性的組件的關鍵是使它們獨立於頁面的任何其餘部分,並自成一體。你應該能把一個組件放到頁面的任何位置,它都將保持它的結構和設計。
狀態累是幫助修改一個組件的狀態。定義手風琴的展開或收起,連接的有效或無效,元素的隱藏或顯示(visible)。在 JavaScript 中常見的添加、刪除狀態 class。你只能更新一個狀態 class 和容許樣式像定義的樣子,而不是用 JavaScript 去直接操做樣式。
主題類只需改變一個組件,使用惟一的顏色、字體或其餘裝飾。主題類能用來修改整個頁面或只是一個的組件。主題不是在每個項目中都必須的,但當你須要的時候再使用它們。
<blockquote class="c-pullquote t-light"> <p>A great quote from someone special.</p> </blockquote>
工具集類是單一目的,幫助咱們應用一個特殊樣式規則。它們能用來修改間隙、增長字體大小、居中文本、添加一個浮動清除 (clearfix),隱藏等等。工具集能幫助你對佈局進行微調,像添加組件之間的間隙或者清除浮動。它們也能夠用來對現有組件進行微調,而不須要建立一個新的組件。
.u-sp { margin-bottom: 1em !important; } .u-clearfix:after { content: " "; display: block; clear: both; visibility: hidden; height: 0; font-size: 0; } .u-txt-center { text-align: center !important; } .u-txt-larger { font-size: 130% !important; }
<div class="promo u-sp"></div> <div class="promo u-sp"></div> <div class="promo"></div>
不管何時,解除你的 JavaScript 和樣式的耦合。將類名既用於樣式又用於 DOM 選擇的 JavaScript 勾子,當 CSS 被重構的時候,JavaScript 的依賴就不清晰明瞭。相反,JavaScript 勾子類就是用來專一處理這類問題的。
<button class="btn btn--buy js-buy-now"></button>
當你對類進行命名的時候,確保你的名字足夠長,可以清晰表達(.pullquote 而不是縮寫的 .pq 來表達意思),可是有一些是不須要的(.nav 不用 .navigation)。類命名的可讀性能幫助團隊成員如今和未來對你表達背後的邏輯的理解有重要的影響。
在編寫 CSS 的時候建立具備描述性的、有意義的名稱是最棘手的問題,若是能仔細考慮將頗有幫助。本文有限不可以對命名的事情討論得太深刻,可是能看一下咱們很是棒的文章,命名 CSS 真的很難-Ethan Muller,這篇文章對這個事情講解得更詳細。
BEM(Block Element Modifier)命名 CSS 組件的方式是很是流行、特別有幫助的規範。該規範來自於俄羅斯的搜索引擎-Yandex。這種命名方式很是簡單:
[BLOCK]__[ELEMENT]-[MODIFIER]
你可能使用這種冗長的類名稱很不習慣,但在你的項目中使用 BEM 將很快去掉這種擔憂。下面是一個使用 BEM 來命名組件的例子:
<div class="alert alert--warning"> <h1 class="alert__title"> <span class="alert__icon"></span> Alert Title </h1> <p class="alert__description">The password you entered is invalid.</p> </div>
BEM 命名有三個主要的好處:
可讀性:大多數元素的類名使用清晰的描述,能使其餘人更容易閱讀你的 HTML 或者 CSS 文件。
自描述:使用分等級的類命名,能使它很是清晰的描述這個組件屬於哪個基本組件。
特殊性:它可能在你的組件的每個元素添加一個類的方式有點過了,可是,經過這樣作,你能保持你的每一個選擇器都有特異性,讓覆蓋權重更加直接。
另外最好的實踐就是當命名你的類名的時候,使用命名空間前綴來進行分類。這些前綴會在你的命名前添加一組字符,可是這個值能馬上標記每個類的目的,在你看 HTML 或者樣式的時候是很須要的。我使用下面這些命名空間:
對象類:.o-
組件:.c-
狀態類:.is-
或者 .has-
主題:.t-
工具類:.u-
JavaScript 勾子:.js-
<footer class="c-footer"> <div class="o-container-wide"> <a class="c-footer__logo" href="/">The Assist</a> <div class="c-social c-social--follow"> <div class="c-social__label u-txt-center">Join the conversation</div> <ul class="c-social__list"> <li class="c-social__item"></li> <li class="c-social__item is-active"></li> <li class="c-social__item"></li> </ul> </div> <p class="c-footer__credit"></p> </div> </footer>
關於更多關於命名空間的信息,能夠看 Harry Roberts's post on the subject
像其餘代碼同樣,你的 CSS 項目使用一致的編碼風格是很重要的。這包括空格,縮進,命名約定,註釋,等你能閱讀一些好的規範,好比:Google,Github 或者 Nicolas Gallagher。使用他們或者建立你本身更適合的規範。
對於較好的代碼組織,您應該使用預處理工具(Sass,Less,Stylus)或者後處理器(PostCSS)去編譯你的代碼。他們有不少優勢,包括一些功能,好比:變量、函數、混淆、導入以及嵌套。這些功能將能讓你有更多的方式去組織 CSS 架構,比你只用 CSS 來作更容易。
使用導入,你能將你的樣式分解到多個文件中。
@import "variables"; @import "mixins"; @import "normalize"; @import "typography"; @import "headings"; @import "headings"; @import "layout"; @import "carousel";
任何值須要屢次使用的時候能定義變量。給你的變量名添加前綴,能幫助識別他們的目的,也爲了使代碼完成更有用。
// Colors $c-warning: Red; $c-primary: Blue; $c-background: White;
一些變量是須要全局定義的,應該存儲在單獨的變量文件中,但其餘變量只被用於單個的組件,這就應該在使用它們的文件中定義。在 SASS 中,變量能夠包含在嵌套的局部範圍內。
.alert { $background-color: Red; $foreground-color: Cream; background-color: $background-color; color: $foreground-color; }
注:其實這裏準備來應該是 SCSS 語法,由於 SASS 語法是不須要花括號的。
因爲 CSS 層級樣式的性質,你的樣式順序多是一個問題。若是你不肯定樣式導入的順序,你將發現你本身始終在級聯問題上是頭疼的。
最近,Harry Roberts 發佈了一篇 a sensible method for ordering your styles (一種使用的排序方法)他稱爲 ITCSS (Inverted Triangle CSS),目的在於防止命名衝突、特殊性的問題,很差的風格以及無心的回退(能夠看他的 Slide in-depth slides)。這個概念很簡單:以影響最小範圍和最低特殊性的樣式規則做爲排序的開始,一直到最靠近選擇元素的和最高特殊性的樣式結尾。這意味着你的變量定義和基本元素規則將老是在最開始,然而你的工具類和 IE hack 將老是在最後。
Harry 定義了七組,適合咱們文件應該排序的分組:
設置(Settings):變量和其餘設置
工具(Tools):自定義函數和混淆
經常使用的(Generic):Font-face,box-sizing,normalize 等等
元素(Elements):純元素默認值,好比標題和連接
對象類(Objects):佈局和結構類
組件(Componets):獨立組件
(Trumps):工具類和其餘規則,這意味着在其餘一切都是放到最後的
@import "settings.global"; @import "settings.colors"; @import "tools.functions"; @import "tools.mixins"; @import "generic.box-sizing"; @import "generic.normalize"; @import "elements.headings"; @import "elements.links"; @import "objects.wrappers"; @import "objects.grid"; @import "components.nav"; @import "components.buttons"; @import "components.promos"; @import "trumps.utilities"; @import "trumps.ie8";
本文只介紹了從深度和廣度上大量的主題,可是我但願它可以讓你在組織和設計項目中的 CSS 的時候更多的思考。若是你想在之後深刻這個主題,這篇文章有大量的資源連接,以及關注更多在這個領域的思想領袖的資源。
Harry Roberts - 目前該領域最豐富的思想領袖之一。可以關注他的 Twitter,訂閱他的博客,閱讀他的 CSS Guidelines 文檔。
Jonathan Snook - 他的 CSS 架構想法很受歡迎,以及他的紙質和電子書,Scalable and Modular Architecture for CSS
Nicole Sullivan - 介紹過 OOCSS(Object Oriented CSS) 的概念,可以翻閱文檔 Github wiki
這篇文章主要是基於最近在相同主題的分享。能檢出 slides for the presentation 或者觀看下面的視頻。
視頻容易掛,這裏我直接貼連接,你們能夠直接點看在瀏覽器播放就好了。
https://player.vimeo.com/video/172444121?byline=0&portrait=0
原文出自:https://seesparkbox.com/foundry/thoughtful_css_architecture
博客原文地址:http://60sky.com/post/thoughtful-css-architecture.html