咱們看一下CSS是怎麼規範的:使用有意義的或通用的ID和class命名。ID和class的命名應反映該元素的功能或使用通用名稱,而不要用抽象的晦澀的命名。反映元素的使用目的是首選;使用通用名稱表明該元素不表特定意義,與其同級元素無異,一般是用於輔助命名;使用功能性或通用的名稱能夠更適用於文檔或模版變化的狀況。css
經常使用命名(多記多查英文單詞):page、wrap、layout、header(head)、footer(foot、ft)、 content(cont)、menu、nav、main、submain、sidebar(side)、logo、banner、 title(tit)、popo(pop)、icon、note、btn、txt、iblock、window(win)、tips等前端
注:類型選擇器避免同時使用標籤、ID和class做爲定位一個元素選擇器;從性能上考慮也應儘可能減小選擇器的層級。vue
你們都說CSS學和寫都簡單,那麼寫了多年CSS的同窗是否有靜下來思考過,本身寫CSS是有較爲系統的和具備必定規範的,而不是草率的寫CSS。另外就是本身寫的CSS在團隊中,別的同窗是否能看到代碼就知道您寫的是什麼?若是沒有,那不仿看看這裏提到的一些概念與思想,好比:Sass 、SCSS、LESS、BEM、OOCSS、AMCSS等。讓咱們一塊兒來深刻了解css吧?webpack
首先了解一下BEM(我我的比較喜歡的)程序員
BEM的意思就是塊(block)、元素(element)、修飾符(modifier),是由Yandex團隊提出的一種前端命名方法論。這種巧妙的命名方法讓你的CSS類對其餘開發者來講更加透明並且更有意義。BEM命名約定更加嚴格,並且包含更多的信息,它們用於一個團隊開發一個耗時的大項目。web
命名約定的模式以下:chrome
.block{} // 塊便是一般所說的 Web 應用開發中的組件或模塊。每一個塊在邏輯上和功能上都是相互獨立的。
小程序
.block__element{} // 元素是塊中的組成部分。元素不能離開塊來使用。BEM 不推薦在元素中嵌套其餘元素。
瀏覽器
.block--modifier{} // 修飾符用來定義塊或元素的外觀和行爲。一樣的塊在應用不一樣的修飾符以後,會有不一樣的外觀。
框架
BEM不是一個框架,它只是一種思想
優勢:BEM 的優勢在於所產生的 CSS 類名都只使用一個類別選擇器,能夠避免傳統作法中因爲多個類別選擇器嵌套帶來的複雜的屬性級聯問題。在 BEM 命名規則中,全部的 CSS 樣式規則都只用一個類別選擇器。所以全部樣式規則的特異性(specificity)都是相同的,也就不存在複雜的優先級問題。這能夠簡化屬性值的層疊規則。代碼清單中的命名規則的好處在於每一個 CSS 類名都很簡單明瞭,並且類名的層次關係能夠與 DOM 節點的樹型結構相對應。 缺點: CSS 類名會比較長並且複雜。乍看之下,根據 BEM 命名規則產生的 CSS 類名都會很複雜,但實際上在熟悉了命名規則以後,能夠很容易理解其含義。
咱們再看一下OOCSS(面向對象CSS)
OOCSS 表示的是面向對象 CSS(Object Oriented CSS),是一種把面向對象方法學應用到 CSS 代碼組織和管理中的實踐。 OOCSS最關鍵的一點就是:提升他的靈活性和可重用性。這個也是OOCSS最重要的一點。OOCSS主張是經過在基礎組件中添加更多的類,從而擴展基礎組件的CSS規則,從而使CSS有更好的擴展性。
咱們有一個容器是頁面page的1/4寬,有一個藍色的背景,1px灰色的邊框,10px的左右邊距,5px的上邊距,10px的下邊距,之前對於這樣一個樣式,咱們經常給這個容器建立一個類,並把這些樣式所有加上。像下面這樣。
1 // template 2 3 <div class="size1of4"></div> 4 5 // style 6 7 .size1of4 { 8 9 background: blue; 10 11 border: 1px solid #ccc; 12 13 margin: 5px 10px 10px; 14 15 width: 25%; 16 17 }
然而使用oocss的話,咱們不這樣作,我把爲這個容器建立更多的類,而且每一個樣式對應一個類,這樣是爲了後面能夠重複使用這些組件的樣式,避免重複寫相同的樣式,就拿這個實例來講,咱們給這個容器增長下面的類:bgBlue,solidGray,mts,mlm,mrm,mbm
1 // template 2 3 <div class="size1of4 bgBlue solidGray mts mlm mrm mbm"></div> 4 5 // style 6 7 .size1of4 {width: 25%;} 8 9 .bgBlue {background:blue} 10 11 .solidGray {border: 1px solid #ccc} 12 13 .mts {margin-top: 5px} 14 15 .mrm {margin-right: 10px} 16 17 .mbm {margin-bottom: 10px} 18 19 .mlm {margin-left: 10px}
OOCSS的優勢
減小CSS代碼。
具備清潔的HTML標記,有語義的類名,邏輯性強的層次關係。
語義標記,有助於SEO。
更好的頁面優化,更快的加載時間(由於有不少組件重用)。
可擴展的標記和CSS樣式,有更多的組件能夠放到庫中,而不影響其餘的組件。
能輕鬆構造新的頁面佈局,或製做新的頁面風格。
OOCSS的缺點
OOCSS適合真正的大型網站開發,由於大型網站用到的可重用性組件特別的多,若是運用在小型項目中可能見不到什麼成效。因此用不用OOCSS應該根據你的項目來決定。
若是沒用巧妙的使用,建立組件可能對於你來講是一堆沒用的東西,成爲一爛攤子,給你的維護帶來意想不到的杯具,說不定仍是個維護的噩夢。
最好給每個組件備寫一份說明文檔,有助於調用與維護。
AMCSS(屬性模塊)。
屬性模塊或者說AM,其核心就是關於定義命名空間用來寫樣式。通俗的講就是,給一個元素加上屬性,再經過屬性選擇器定位到這個元素。達到避免過多的使用class。
1 // template 2 3 <div am- Row ></div> 4 5 <div am- Column = "12"> Full < /div> 6 7 </ div> <div am- Row > <div am- Column = "4"> Thirds </div> 8 9 <div am- Column = "4"> Thirds </div> 10 11 <div am- Column = "4"> Thirds < /div> </ div> 12 13 // style 14 15 [am- Row ] { /* max-width, clearfixes */ } 16 17 [am- Column ~= "1" ] { /* 1/12th width, floated */ } 18 19 [am- Column ~= "2" ] { /* 1/6th width, floated */ } 20 21 [am- Column ~= "3" ] { /* 1/4th width, floated */ } 22 23 [am- Column ~= "4" ] { /* 1/3rd width, floated */ } 24 25 [am- Column ~= "5" ] { /* 5/12th width, floated */ } /* etc */ 26 27 [am- Column ~= "12" ] { /* 100% width, floated */ }
你會注意到第一件事情就是有am-前綴。這也是AM核心部分,確保屬性模塊不會與現有屬性衝突。你可使用你本身喜歡的任何前綴名,我常使用的是ui-、css-或者其餘前綴,但這些示例中使用的是am-前綴。HTML的有效性對你或你的項目來講是很是重要,就相似於使用data-前綴開頭定義的屬性相似。 你可能會注意到的第二件事情就是相似於一、4或12這樣的值,使用類名變得極爲麻煩——形成衝突的機會不少。但定義了咱們本身的命名空間,實際上將空間變得很小,用於工做中不會形成衝突。爲了更好的工做,能夠自由選擇最簡明並且有意義的標記。
咱們雖然有這麼多的好的方案去解決css的一些難題,可是有沒有一種東西或者工具來代替咱們去作這些呢,做爲一個程序員咱們不喜歡作太麻煩的事情。那麼接下來咱們談一談css的構建工具
With :local (without brackets) local mode can be switched on for this selector. :global(.className) can be used to declare an explicit global selector. With :global (without brackets) global mode can be switched on for this selector. webpack會把class分爲兩種,一種是local(本地的),一種是global(全局的)。默認導出的都是本地的,可是你能夠經過 :global(...)開關來控制導出全局。下面咱們看一下栗子。
1 // 輸入 2 3 : local (.className) { background: red; } 4 5 : local .className { color: green; } 6 7 : local (.className .subClass) { color: green; } 8 9 : local .className .subClass : global (. global - class -name) { color: blue; } 10 11 // 導出 12 13 ._23_aKvs-b8bW2Vg3fwHozO { background: red; } 14 15 ._23_aKvs-b8bW2Vg3fwHozO { color: green; } 16 17 ._23_aKvs-b8bW2Vg3fwHozO ._13LGdX8RMStbBE9w-t0gZ1 { color: green; } 18 19 ._23_aKvs-b8bW2Vg3fwHozO ._13LGdX8RMStbBE9w-t0gZ1 . global - class -name { color: blue; }
:local(className)被編譯爲惟一可識別的標示,:global(className)原樣輸出,固然咱們也能夠控制導出的格式。配置以下:
1 { 2 3 test: /\.css$/ , 4 5 use : [ 6 7 { 8 9 loader: 'css-loader', 10 11 options: { 12 13 modules: true , 14 15 localIdentName: '[path][name]__[local]--[hash:base64:5]' 16 17 } 18 19 } 20 21 ] 22 23 }
如今在各類框架中都會有scoped屬性,使咱們的css具備模塊化性質,不會污染到其餘模塊,那麼scoped是如何實現的呢?咱們一塊兒來揭開它神祕的面紗吧?
若是你是一個勤奮好學的同窗,你必定會發如今HTML的style標籤中有一個scoped屬性。讓咱們來一塊兒看一下這個屬性的神奇吧。
一直以來,文檔上的STYLE元素一般都是做用域全局的,選擇器按照全局的CSS優先規則來設置的。要實現局部的選擇須要先選到容器元素,再用後代選擇器來實現。scoped屬性可讓STYLE元素再也不做用於全局,而從當前STYLE元素所在的容器開始選擇後代。
1 <div> 2 3 <style scoped > 4 5 span {color:red;} 6 7 </style> 8 9 <span> 我是第1個DIV內的SPAN </span> 10 11 </div> 12 13 <div> 14 15 <style scoped > 16 17 span {color:green;} 18 19 </style> 20 21 <span> 我是第2個DIV內的SPAN </span> 22 23 </div> 24 25 <div> 26 27 <span> 我是第3個DIV內的SPAN </span> 28 29 </div>
結果:
咱們能夠看見第三個div並無被第一及第二個style所感染,也就是說帶有scoped屬性的css是一個獨立的做用域,不會影響到其它模塊!!太好了,那咱們之後在style裏面加上scoped屬性就能夠完美解決啦慢!BUT,這種方法只有在火狐瀏覽器才生效,其它瀏覽器即便最新的chrome瀏覽器也不支持哦。我@#¥%……
不要急年輕人,咱們來看一下vue的代碼,當咱們在style中加了scoped屬性後
咦,這不就是咱們剛剛講過的AMCSS(屬性模塊)的應用嗎?也就是說vue在編譯的時候,把帶有scoped屬性的的模塊,加上了一個惟一的屬性,而後經過類名+屬性選擇器的方法來實現模塊化!
其實其餘框架也是用的相似的方法,咱們再看一下,小程序wepy框架的實現吧?
這個是咱們剛纔講過OOCSS(面對對象CSS)!!
對的,這樣結合框架來說是否是可以更能深入理解咱們剛纔講過的內容了啊?
有時候咱們須要把一些有用的常見的css放到一個common.css裏面,可是當咱們項目足夠大的時候,common的內容就會變得異常龐大,並且難以維護。
首先咱們不得不說一下當下有幾個比較火的CSS預處理器,Less、Sass 、Stylus和postCss,這是一個CSS史上的巨大飛躍。他主要提供瞭如下功能
嵌套語法
變量
@import
混入
繼承
函數
邏輯控制
瞭解了css預處理器,那麼咱們如何優化咱們的common.css呢?
要想解決這個問題,咱們首先來看一看LESS中的mixin是如何運做的。
1 // 你能夠混合「類」選擇器或者「id」選擇器,例如: 2 3 .a, #b { 4 5 color: red; 6 7 } 8 9 .mixin-class 10 11 { 12 13 .a(); 14 15 } 16 17 .mixin-id { 18 19 #b(); 20 21 }
以上將獲得:
1 .a, #b { 2 3 color: red; 4 5 } 6 7 .mixin-class 8 9 { 10 11 color: red; 12 13 } 14 15 .mixin-id { 16 17 color: red; 18 19 }
小提示:當你調用混合集的時候,括號可加可不加。
1 .a(); //這兩種調用方式效果是同樣的 2 3 .a;
若是你想要建立一個混合集,可是卻不想讓它輸出到你的樣式中,你能夠在混合集的名字後面加上一個括號。
1 .my-mixin { 2 3 color: black; 4 5 } 6 7 .my-other-mixin() { 8 9 background: white; 10 11 } 12 13 .class { 14 15 .my-mixin; 16 17 .my-other-mixin; 18 19 }
輸出:
1 .my-mixin { 2 3 color: black; 4 5 } 6 7 .class { 8 9 color: black; 10 11 background: white; 12 13 }
好了,咱們知道這個原理就能夠用less中的mixins從新修改咱們的common.less了,並且不會顯得很是臃腫,咱們能夠按需加載咱們的樣式了,是否是很棒啊
咱們的CSS模塊化就講到這裏了,有什麼意見或建議能夠聯繫我哦!