標籤:style blog http color 使用 os strong io
前情提要
- 使用 Bootstrap 和 HTML5 Boilerplate 開始一個項目
- 使用 Bootstrap 和 HTML5 Boilerplate 開始一個項目續
在前面,我建立了一個簡單的首頁,但是現在遇到問題了,我不能滿足於 Bootstrap 的預設樣式,希望能夠根據自己的需求來定義樣式,所以,為了能夠愉快地修改樣式,我需要先來理解一下基本的 Less 文法,更多詳細資料可以參考官網
Less 是一個 CSS 前置處理器,使用類似於 CSS 的文法,對 CSS 做了很多改進,不過,最後都應該編譯成可直接供瀏覽器識別的 CSS 檔案,其優勢主要在於提升了開發速度以及可以更好地組織樣式表。在項目初期我已經安裝好 Less 了,安裝方法還是一樣,在node.js中使用Node包管理工具npm來安裝,首先,去 http://nodejs.org/download/ 根據自己的作業系統下載對應的 Node 安裝版本,由於我是使用的是 Windows XP,所以我下載了那個 node-v0.10.29-x86.msi 傻瓜式安裝包:
下載完成後,雙擊該檔案就可以安裝了,當然我安裝 Node 並不是為了使用它,而是為了使用 Node 包管理工具 NPM,NPM 是一個NodeJS包管理和分發工具,類似於 Ruby 的 gem,在 Node 0.4及以後的版本中,NPM 已經歸入 Node 核心中了,所以不用再另外安裝了,查看一下 NPM 的版本以確定已經安裝成功:
npm -v
列印出來的數字就是版本號碼,經常更新 NPM 也是一個好習慣:
npm update -g npm
確認安裝好了以後就可以安裝 Less 了,在全域環境中安裝 Less:
npm install -g less
如果去掉 -g 標識就是局部安裝,那麼就會安裝在執行命令的路徑下面,通常會選擇項目的路徑,由於我會在幾乎所有項目中都使用 Less 開發,所以全域安裝也沒什麼不妥,安裝完成後可以檢查一下 Less 的版本:
同樣列印出版本號碼表示安裝是成功了的,需要注意這裡的命令是 lessc (不是 less),也就是 Less Compiler,編譯 Less 檔案的時候也是使用這個命令,目前的版本和官網上面一致,如果版本較低,可以試試升級:
npm update less -g
安裝完成後就可以使用了,Less 檔案的尾碼名就是 .less,可以將一個普通 CSS 檔案通過修改尾碼名的方式來快速產生一個 Less 檔案,不過,還是先來看看 Less 有些什麼特性:
變數
變數可以用來儲存準備多次使用的資訊,只需要定義一次就能反覆使用,如果對變數定義做了修改,那麼所有使用了該變數的執行個體都會隨之改變,試想,如果頁面中使用了很多 #abc 這個顏色值,某一天希望全部修改為 #def,那麼只需要修改一個變數的值就可以了,而不是無聊的尋找替換。在 Less 中使用 @ 符號作為變數名首碼,變數名和變數值之間用 : 分隔,最後用 ; 結束變數申明:
@brand-primary: #428bca;
使用變數就像使用一個 CSS 屬性值一樣:
a { color: @brand-primary;}
儲存為一個 Less 檔案,比如 example.less,然後使用如下命令編譯成 CSS 檔案:
lessc example.less > example.css
不要那個大於符號也可以(我也不知道要不要有什麼區別),編譯好後的 example.css 如下:
a { color: #428bca;}
可以任意地使用變數,通常情況下,後申明的同名變數會覆蓋之前申明的值,也可以在申明變數之前就使用該變數,變數申明會提前。在 Bootstrap 的 Less 檔案裡面找到 variables.less 檔案(在這個項目中的路徑是 less/bootstrap/variables.less),可以看到裡面申明了很多變數,隨意修改裡面的變數值,然後重新編譯即可定製化 Bootstrap 的樣式。
嵌套規則
使用嵌套可以更合理地組織同一模組下的樣式表,比如,下面是 navbar 模組的樣式:
.navbar-nav { ... }.navbar-nav > li { ... }.navbar-nav > li > a { ... }.navbar-nav > li > a:hover,.navbar-nav > li > a:focus { ... }
反覆書寫 .navbar-nav... 就算是複製粘貼也讓人覺得噁心,好在 Less 裡面可以使用大括弧嵌套文法:
.navbar-nav { ... > li { ... > a { ... &:hover, &:focus { ... } } }}
編譯後產生的 CSS 檔案和上面基本一致,可以看到,使用嵌套規則提高了書寫樣式的效率,雖然編譯後的 CSS 樣式檔案並沒有什麼實質變化,但是 Less 檔案可以更容易編寫和維護。
& 符是父元素引用符,在這裡 & 就相當於引用 navbar-nav > li > a,如上,使用父元素引用符可以簡化偽類、虛擬元素樣式的編寫,另外可以將選取器進行調換:
.main { .content { width: 70%; } .content & { width: 100%; } .content & { .two & { color: pink; } }}
產生 CSS 代碼如下:
.main .content { width: 70%;}.content .main { width: 100%;}.two .content .main { color: pink;}
也可用於建立多類別選取器(級聯選取器):
.collapse { &.in { display: block; }}
產生 CSS 代碼如下:
.collapse.in { display: block;}
該選取器選擇的是同時具有這兩個 class 的元素。
在嵌套裡面申明的變數為局部變數,嵌套之外的環境不能使用該變數:
a { color: @brand-primary; @brand-primary: #428bca;}div { background-color: @brand-primary; // NameError: variable @brand-primary is undefined}
同樣,在局部修改變數後不會對嵌套之外的環境產生影響:
@brand-primary: #428bca;a { color: @brand-primary; // #c1ba62 @brand-primary: #c1ba62;}div { background-color: @brand-primary; // #428bca}
還有一種是玩法是本項目已經引入了 Modernizr.js 指令碼,該指令碼會在頁面載入的時候檢測瀏覽器的特性,根據瀏覽器支援與不支援某些特性而在 html 元素上添加了很多 class:
這是我用 Chrome 24.0 開啟看到的效果,可以看到該瀏覽器對這些特性的支援都很好,對於不支援的特性前面有個 no- 首碼,比如 csstransform3d 是不支援的,因此寫樣式的時候可以像下面這樣寫:
div { ... // 支援 3d 變換時的樣式 .no-csstransform3d & { ... // 不支援 3d 變換時的樣式 }}
當然,這個例子並不是很恰當!
混合
混合(mixin)是指可重用的一段代碼,最常見的應用是為實驗性 CSS 屬性處理瀏覽器首碼,比如說我要使用過渡(transition)屬性,為了相容更多主流瀏覽器,我可能會這樣寫:
-webkit-transition: all .2s ease-in-out; transition: all .2s ease-in-out;
那我所有使用過渡屬性的地方都得這樣寫,比較麻煩,定義成一個 mixin 的話,就像這樣:
.transition(@transition) { -webkit-transition: @transition; transition: @transition;}
調用的時候只要傳入參數就可以了:
.thumbnail { .transition(all .2s ease-in-out);}
好處是寫的時候不用反覆寫同一條屬性的各種首碼了,同樣,如果以後不再需要帶某個首碼的屬性了,那麼只需要修改一下定義的 mixin 然後再重新編譯一次就 OK 了,當然混合的威力遠遠不止如此。
運算
在 Less 的世界裡可以進行數學運算,比如可以使用函數加深一個顏色的值:
a:hover { darken(@link-color, 15%);}
也可以進行常見的四則運算:
.navbar > li > a { padding-top: ((@navbar-height - @line-height-computed) / 2); padding-bottom: ((@navbar-height - @line-height-computed) / 2);}匯入檔案
使用匯入檔案功能可以將 Less 檔案分為不同的模組組件單獨存放,然後將需要用到的 Less 檔案全部匯入到一個主 Less 檔案中,最後編譯成一個單獨的 CSS 樣式檔案,比如在 less/bootstrap/bootstrap.less 檔案中可以看到:
// Core variables and mixins@import "variables.less";@import "mixins.less";// Reset and dependencies@import "normalize.less";@import "print.less";@import "glyphicons.less";
通常情況下,會先匯入變數、mixins,然後 Reset/重設樣式,接下來再是其它模組。
以上是 Less 的一些準系統,在清楚了之後才能隨心所欲地修改 Bootstrap 的樣式,不過在此期間 Bootstrap 已經升級到 3.2.0 版本了,所以我決定跟上潮流,將 Bootstrap 相關檔案都更新到了官方最新版本(由於之前還沒有編輯過樣式檔案,直接刪除替換掉就可以了)。回到那個可愛的三列內容欄:
<div class="container"> <div class="row"> <div class="col-sm-4"> <h2>Welcome!</h2> <p>Suspendisse et arcu felis ...</p> <p><a href="#">See our portfolio</a></p> </div> <div class="col-sm-4"> <h2>Recent Updates</h2> <p>Suspendisse et arcu felis ...</p> <p><a href="#">See what‘s new!</a></p> </div> <div class="col-sm-4"> <h2>Our Team</h2> <p>Suspendisse et arcu felis ...</p> <p><a href="#">Meet the team!</a></p> </div> </div><!-- end .row --></div><!-- end .container -->
Bootstrap 定義了4類網格 class,以適應不同的螢幕解析度,分別以 col-xs,col-sm,col-md,col-lg 為首碼,col-xs 表示就算在超小螢幕下列也會浮動並呈現為網格樣式,col-sm 表示只在小螢幕及以上會呈現為網格樣式、而在超小螢幕下列就不會再浮動,而是佔滿整行,類似的 col-lg 列就只會在大螢幕上才浮動,關於各種螢幕解析度的斷點在 bootstrap/variables.less 裡面有詳細定義。
因為我不想使用 col-sm-4 這樣的 class,所以先將這些 class 替換掉,為了避免和 Bootstrap 命名衝突,我都為自訂 class 加上了首碼,當然這個首碼不代表任何意思:
<div class="container"> <div class="row"> <div class="x-column"> <h2>Welcome!</h2> <p>Suspendisse et arcu felis ...</p> <p><a href="#">See our portfolio</a></p> </div> <div class="x-column"> <h2>Recent Updates</h2> <p>Suspendisse et arcu felis ...</p> <p><a href="#">See what‘s new!</a></p> </div> <div class="x-column"> <h2>Our Team</h2> <p>Suspendisse et arcu felis ...</p> <p><a href="#">Meet the team!</a></p> </div> </div><!-- end .row --></div><!-- end .container -->
先在 less 檔案夾裡面建立一個 main.less 的檔案,把 bootstrap.less 匯入進來,就相當於把所有 Bootstrap Less 檔案都匯入進來了,然後後面再匯入一個自己建立的 Less 檔案,就叫 custom.less 吧:
@import "bootstrap/bootstrap.less";@import "costom.less";
在 custom.less 中輸入如下代碼:
.x-column { .make-sm-column(4);}
這裡使用了 Bootstrap 預定義的 mixin,然後重新編譯:
lessc less/main.less css/main.css
編譯之後的相關 CSS 如下,可以在 main.css 的最末尾看到:
.x-column { position: relative; min-height: 1px; padding-left: 15px; padding-right: 15px;}@media (min-width: 768px) { .x-column { float: left; width: 33.33333333%; }}
由於我添加了自己定義的樣式,同時我也不樂意在一個頁面中添加多個樣式檔案(增加了 HTTP 要求),所以我把 Bootstrap 的樣式和我自己定義的樣式都整合到了一個樣式檔案中,這樣一來就不好意思再用 bootstrap.css 這個檔案名稱了,所以我改成了 main.css。index.html 頁面上的內容也得隨之更新一下,這個不能忘記:
<link rel="stylesheet" href="css/main.css">
最終得到的效果和使用 col-sm-4 這個 class 是一樣的,為什麼這麼做呢?這樣如果我想一個內容欄佔滿整行,而不是一行三列,那麼我只要修改 Less 檔案就可以了,而不是去修改 HTML:
.x-column { .make-sm-column(12);}
就這麼簡單,可以參考一下 Bootstrap 的 mixins 檔案查看更多資訊。
資源清單
- Bootstrap
- HTML5 Boilerplate
- Less
- Modernizr
- Node.js