談談PostCSS

什麼是CSS

css,是一種樣式腳本,好像和編程語言有着一定的距離,我們可以將之理解爲一種描述方法。這似乎導致css被輕視了。不過,css近幾年來正在經歷着一次鉅變——CSS Module。

我記得js的井噴期應該可以說是node帶來的,它帶來了Module的概念,使得JS可以被工程化開發項目

CSS預處理器的介紹

目前,在工程化開發中,使用最多的應該就是Less、Sass和Stylus。

首先,還是介紹一下它們吧。它們有個統一的名字——css預處理器。何爲CSS預處理器?應該就是一種可以將你根據它的規則寫出來的格式轉成css的東西(還是講的通俗一點)。它們的出現可以說是恰逢其時,解決了css的一些缺憾:

  • 語法不夠強大,不能夠嵌套書寫,不利於模塊化開發
  • 沒有變量和邏輯上的複用機制,導致在css的屬性值中只能使用字面量形式,以及不斷重複書寫重複的樣式,導致難以維護。

面對以上問題,css預處理器給出了非常可行的解決方案:

1.變量:就像其他編程語言一樣,免於多處修改。

  • Sass:使用「$」對變量進行聲明,變量名和變量值使用冒號進行分割
  • Less:使用「@」對變量進行聲明
  • Stylus:stylus中聲明變量沒有任何限定,結尾的分號可有可無,但變量名和變量值之間必須要有『等號』。但需要注意的是,如果用“@”符號來聲明變量,Stylus會進行編譯,但不會賦值給變量。就是說,Stylus不要使用『@』聲明變量。Stylus 調用變量的方法和Less、Sass完全相同。

2.作用域:有了變量,就必須得有作用域進行管理。就像js一樣,它會從局部作用域開始往上查找變量。

  • Sass:它的方式是三者中最差的,不存在全局變量的概念
  • Less:它的方式和js比較相似,逐級往上查找變量
  • Stylus:它的方式和Less比較相似,但是它和Sass一樣更傾向於指令式查找

3.嵌套:對於css來說,有嵌套的寫法無疑是完美的,更像是父子層級之間明確關係

  • 三者在這處的處理都是一樣的,使用「&」表示父元素

有了這些方案,會使得我們可以在保證DPY、可維護性、靈活性的前提下,編寫css樣式。

回到話題中,之所以會出現像預處理器這樣子的解決方案,歸根結底還是css標準發展的滯後性導致的。同時,我們也應該考慮一下,真的只要預處理器就夠了嗎?

往往在項目過大時,由於缺乏模塊的概念,全局變量的問題會持續困擾着你。每次定義選擇器時,總是要顧及到其他文件中是否也使用了同樣的命名。畢竟項目是團隊的,而不是個人的。那是否有方式可以解決這些問題呢?

前人的方法

對於css命名衝突的問題,由來已久,可以說我們前端開發人員,天天在苦思冥想,如何去優雅的解決這些問題。css並未像js一樣出現了AMD、CMD和ES6 Module的模塊化方案。

那麼,回到問題,如何去解決呢?我們的前人也有提出過不同的方案:

  1. Object-Oriented CSS
  2. BEM
  3. SMACSS

方案可以說是層出不窮,不乏有團隊內部的解決方案。但是大多數都是一個共同點——爲選擇器增加前綴。

這可是一個體力活,你可能需要手動的去編寫長長的選擇器,或許你可以使用預編譯的css語言。但是,它們似乎並未解決本質的問題——爲何會造成這種缺憾。我們不妨來看看,使用BEM規範寫出來的例子:

<!-- 正確的。元素都位於 'search-form' 模塊內 -->
<!-- 'search-form' 模塊 -->
<form class="search-form">
    <!-- 在 'search-form' 模塊內的 'input' 元素 -->
    <input class="search-form__input" />
    <!-- 在 'search-form' 模塊內的 'button' 元素 -->
    <button class="search-form__button"></button>
</form>

<!-- 不正確的。元素位於 'search-form' 模塊的上下文之外 -->
<!-- 'search-form' 模塊 -->
<form class=""search-block>
</form>

<!-- 在 'search-form' 模塊內的 'input' 元素 -->
<input class="search-form__input"/>

<!-- 在 'search-form' 模塊內的 'button' 元素 -->
<button class="search-form__button"></button>

一種希望

現在的網頁開發,講究的是組件化的思想,因此,急需可行的css Module方式來完成網頁組件的開發。自從2015年開始,國外就流行了CSS-in-JS(典型的代表,react的styled-components),還有一種就是CSS Module

對於css,大家都知道,它是一門描述類語言,並不存在動態性。那麼,要如何去形成module呢。我們可以先來看一個react使用postcss的例子:

//example.css

.article {
    font-size: 14px;
}
.title {
    font-size: 20px;
}

之後,將這些命名打亂:

.zxcvb{
    font-size: 14px;
}
.zxcva{
    font-size: 20px;
}

將之命名對應的內容,放入到JSON文件中去:

{
    "article": "zxcvb",
    "title": "zxcva"
}

之後,在js文件中運用:

import style from 'style.json';

class Example extends Component{
    render() {
        return (
            <div classname={style.article}>
                <div classname={style.title}></div>
            </div>
        )
    }
}

這樣子,就描繪出了一副css module的原型。當然,我們不可能每次都需要手動去寫這些東西。我們需要自動化的插件幫助我們完成這一個過程。之後,我們應該先來了解一下postCSS。

參考:http://geek.csdn.net/news/detail/230756
https://github.com/laizimo/zimo-article/issues/41

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章