前言
css
首先閱讀本文以前建議先看一下Bootstrap基礎以及Less簡介,否則你不會知道我在雲什麼.由於最近打算用Bootstrap+Less進行開發,可是Less雖然有一些資料,不過大都是Example類型的,感受比較抽象更像是API,在網上又找不到比較好的解說,因此打算本身寫點.
html
對Bootstrap和Less有興趣的能夠看一下官網(中文):http://www.bootcss.com/和http://www.bootcss.com/p/lesscss/.前端
正文
html5
在Github上維護的Bootstrap項目就是基於Less的,並且做爲目前來說最優秀的前端CSS框架Bootstrap的功底也至關不錯.因此直接看Less在Bootstrap中是如何實現的就能比較好的瞭解了.這裏強調一點就是無論咱們怎麼看Less,最後是爲了寫出本身的東西,因此一切都是靈活的.
java
從https://github.com/twbs/bootstrap上下載到Bootstrap的源代碼,這裏面有一個Less文件夾,咱們研究的重心就是這裏了.如今還缺乏一個Less的編譯環境,能夠用Grunt或者Nodejs,這裏我選擇一個圖形界面軟件koala.
jquery
Bootstrap源碼包含了預先編譯的CSS、JavaScript和圖標字體文件,而且還有LESS、JavaScript和文檔的源碼。具體來講,主要文件組織結構以下:git
bootstrap/
├── less/
├── js/
├── fonts/
├── dist/
│ ├── css/
│ ├── js/
│ └── fonts/
├── docs-assets/
├── examples/
└── *.html
less/
、js/
和 fonts/
分別包含了CSS、JS和字體圖標的源碼。dist/
目錄包含了上面所說的預編譯Bootstrap包內的全部文件。docs-assets/
、examples/
和全部 *.html
文件是文檔的源碼文件。除了前面提到的這些文件,還包含package定義文件、許可證文件等。github
咱們在頁面上使用的時候,其實仍是引入的CSS文件,只不過它是經過.less文件編譯過來的,有點相似java文件和class文件.打開Less文件夾,咱們發現是好多Less文件和一個mixins文件夾.這裏咱們先不研究每一個文件的具體內容,咱們就以一個典型的組件如何實現的去研究它的過程.這裏我選擇的是一個導航欄,因此新建一個頁面,引入經過Less編譯好的文件,而後逐步上溯CSS樣式.
bootstrap
(1) 在Less文件夾外新建一個index.html文件,內容是標準的Bootstrap空白頁便可,而後寫上一個簡單的導航欄,具體代碼能夠參照Bootstrap官網上的導航欄.先上代碼:
app
<!DOCTYPE html> <html> <head> <title>Bootstrap 101 Template</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- Bootstrap --> <link rel="stylesheet" href="css/bootstrap.css"> <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> <!--[if lt IE 9]> <script src="http://cdn.bootcss.com/html5shiv/3.7.0/html5shiv.min.js"></script> <script src="http://cdn.bootcss.com/respond.js/1.3.0/respond.min.js"></script> <![endif]--> </head> <body> <nav class="navbar navbar-default" role="navigation"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Brand</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li class="active"><a href="#">Link</a></li> <li><a href="#">Link</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a> <ul class="dropdown-menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> <li class="divider"></li> <li><a href="#">One more separated link</a></li> </ul> </li> </ul> <form class="navbar-form navbar-left" role="search"> <div class="form-group"> <input type="text" class="form-control" placeholder="Search"> </div> <button type="submit" class="btn btn-default">Submit</button> </form> </div><!-- /.navbar-collapse --> </nav> <!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> <script src="http://cdn.bootcss.com/jquery/1.10.2/jquery.min.js"></script> <!-- Include all compiled plugins (below), or include individual files as needed --> <script src="http://cdn.bootcss.com/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script> </body> </html>
上面代碼看個大概便可,一會還要逐步分析.這裏有幾點要聲明的,第一就是經過Koala將less/bootstrap.less編譯成css/bootstrap.css,就編譯這一個文件便可,它是Bootstrap全部樣式的一個入口.而後咱們在頁面中就要引入這個編譯後的CSS文件,經過不要關閉你的Koala它會繼續監聽這個文件,實時更新.作好上面這些以後,從Bootstrap官網找一段導航欄NavBar的代碼放進入,頁面生成的效果以下:
(2) 分析less的文件組織結構
能夠看到less文件夾內和它裏面mixins文件夾內都有許多less文件,mixins是less的功能中的混入,以此命名說明其中的less大多數功能代碼.在Bootstrap中咱們要研究的文件是:less文件夾中的bootstrap.less(全部樣式的對外接口),variables.less(存儲全部的less變量),以及帶有nav或者navbar字樣的less文件.目前能想到的和導航欄有關的大概就是這樣,而後開始先看一下Bootstrap.less.
若是對全部的less的結構和做用不清楚,必定要看一下bootstrap.less,這裏面對less文件的一個組織結構基本上能夠算做是標準了,我在註釋里加了中文解釋,下面就是代碼:
// Core variables and mixins(最開始引入全部的變量,以及混入規則,這兩個應該是各個less的基礎.按照less官網說不須要提早定義,less支持按需加載就是須要的時候它本身去找,不過仍是建議先加載進來.) // 這裏mixins.less中內容和bootstrap.less相似,沒有實際代碼,全是@import引入mixins文件夾的內容. @import "variables.less"; @import "mixins.less"; // Reset and dependencies // 這3個less,第一個是重置基本樣式,第二個是針對打印機打印時的樣式設置,第三個是圖標.也就是說這3個也是基礎的支撐文件. @import "normalize.less"; @import "print.less"; @import "glyphicons.less"; // Core CSS // 什麼叫core,就是核心的東西,這裏面的一些腳手架,柵格,表格,表單,按鈕,這些都是基礎的樣式,也是Bootstrap展現的核心. @import "scaffolding.less"; @import "type.less"; @import "code.less"; @import "grid.less"; @import "tables.less"; @import "forms.less"; @import "buttons.less"; // Components // 組件就是一些網頁常見的組成部分,它們可能在一個網站中頻繁出現,因此將它們作成組件的形式方便你拿來就用.好比導航,下拉,分頁,提示等等... @import "component-animations.less"; @import "dropdowns.less"; @import "button-groups.less"; @import "input-groups.less"; @import "navs.less"; @import "navbar.less"; @import "breadcrumbs.less"; @import "pagination.less"; @import "pager.less"; @import "labels.less"; @import "badges.less"; @import "jumbotron.less"; @import "thumbnails.less"; @import "alerts.less"; @import "progress-bars.less"; @import "media.less"; @import "list-group.less"; @import "panels.less"; @import "responsive-embed.less"; @import "wells.less"; @import "close.less"; // Components w/ JavaScript // 一些好的效果須要JS支持,JS又須要對CSS樣式進行操做,這些less就是爲了支持JS插件的 @import "modals.less"; @import "tooltip.less"; @import "popovers.less"; @import "carousel.less"; // Utility classes // 所謂的Utility就是公用的,有效用的.看utilities能夠發現其中定義了浮動清除,顯示隱藏等基本幾個樣式,看起來就像是從mixins.less中提取出來的同樣. @import "utilities.less"; @import "responsive-utilities.less";
根據bootstrap.less的代碼能夠清晰的看出其中經過less進行編碼的文件結構,一共就是幾類東西:變量和規則,全局重定義,基礎核心(好比table和form等,在原生基礎上進行了擴展),經常使用組件,支持JS的.
(3) 在相關的文件中尋找對應
清楚了文件的組織結構,而後開始從後往前遞推,看樣式是如何生成的.這時看以前寫好的index.html中代碼,導航欄總體被包裹在一個nav標籤,它的第一個樣式是.navbar,Bootstrap中定義navbar是導航欄的基礎樣式.在頁面上經過Chrome的F12進行樣式查看.最終經過.navbar這個類被應用的樣式以下:
@media (min-width: 768px) .navbar { border-radius: 4px; } .navbar { position: relative; min-height: 50px; margin-bottom: 20px; border: 1px solid transparent; }
第一個是由於媒體設備判斷當前頁面寬度,而後添加了border-radius.後面是經過.navbar添加了position和min-height還有margin-bottom和border.而後經過這些開始尋找navbar的less文件,首先在less文件夾下就有一個navbar.less,其中定義的第一個樣式就是.navbar以下:
// Wrapper and base class // // Provide a static navbar from which we expand to create full-width, fixed, and // other navbar variations. .navbar { position: relative; min-height: @navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode) margin-bottom: @navbar-margin-bottom; border: 1px solid transparent; // Prevent floats from breaking the navbar &:extend(.clearfix all); @media (min-width: @grid-float-breakpoint) { border-radius: @navbar-border-radius; } }
一點點看這個代碼,這個navbar寫的並不複雜.首先它不是一個規則,也就是沒有傳遞參數一說,說明它內部使用的變量的值應該都來自於variables.less文件中的設置.先是定義了position:relative的相對定位,這就與以前頁面上的position相對應上了.而後這裏有一個min-height設定,咱們在頁面上看到的是50px,這裏是經過@navbar-height變量的,去variables.less中找找看是否是這樣.
這裏我直接將variables.less文件中的涉及navbar的地方列出來:
// Basics of a navbar @navbar-height: 50px; @navbar-margin-bottom: @line-height-computed; @navbar-border-radius: @border-radius-base; @navbar-padding-horizontal: floor((@grid-gutter-width / 2)); @navbar-padding-vertical: ((@navbar-height - @line-height-computed) / 2); @navbar-collapse-max-height: 340px; @navbar-default-color: #777; @navbar-default-bg: #f8f8f8; @navbar-default-border: darken(@navbar-default-bg, 6.5%);
看到了吧,高度在這裏設置的是50px.而後咱們注意到navbar樣式的margin-bottom在這裏又引用了@line-height-computed.而後繼續索引這個變量找到它的值是這樣定義的:
@line-height-computed: floor((@font-size-base * @line-height-base)); // ~20px
取字體的基本大小這裏定義的是14px而後乘以基本行高定義的是1.428,如此至關於navbar中的margin-bottom的值就是20px.這個和最終顯示的樣式是相等的,可是這裏咱們看到這個值並非直接設定的,而是根據字體和行高算出來的,在Bootstrap中不少地方應用到這種那方式,也就是牽一髮而動全身.這裏無法一一去理清它變量間的關係,可是從設計的方面咱們能夠知道,這麼作是有好處的,好比字體變大了以後,其它與其配合的地方也會有相應的改變,從而在視覺上造成統一.
而後還有個border: 1px solid transparent;咱們看到這個代碼變量和其它的,就是直接寫死了1px寬而且透明.而後我對navbar.less全局搜索了border,發現都沒有經過變量設置,而是直接設置了寬度.
這樣頁面上顯示的navbar對應的樣式沒了,咱們接着看navbar.less中的navbar樣式,裏面有一段繼承:
&:extend(.clearfix all);
這個的意思很好理解,&表示父級,也就是讓父級.navbar繼承.clearfix樣式.這裏清除浮動的樣式是定義在/mixins/clearfix.less中,裏面只有這一個規則.
(4) 尋找規律進行分析
如今把問題拉回到現實,咱們研究Bootstrap中less的過程是爲了什麼?
咱們的目的是爲了寫出和Bootstrap同樣好的CSS代碼,這纔是咱們的目的.誠然Bootstrap中爲咱們作好了不少如導航之類的組件,可是總有須要咱們本身寫的東西,這時候咱們徹底能夠參照Bootstrap中對於組件的寫法.
從頭查看一遍navbar.less,它並無嵌套不少類,基本上都是單獨列出來的,以應付更靈活的HTML結構.而且組件定義的很細緻,基本上從各個方面都有定義class.固然咱們本身寫的時候應該不用劃分這麼細緻.
這時候在仔細思考一下它的實現步驟:
將可配置的靈活的東西定義爲變量在variables.less中 --> 將可能被其餘地方用到或者通用的規則定義到mixins中 --> 若是能使用Bootstrap的就儘可能使用它自帶的組件 --> 若是本身開發就爲本身的組件單獨一個文件,按照less的寫法靈活的定位佈局以及設置表現樣式.
若是隻是這麼看其實less的寫法和單純CSS沒什麼太大的分別,只不過更加便捷並且加入了一些邏輯.
結尾
在一個大頁面上很是小的一個點被應用了什麼樣式是很繁雜的,我問過不少CSS方面的熟練工,得出的結論就是CSS是一個經驗很重要的東西.作得多了纔會積累出足夠的感受,因此本文也沒辦告訴你先寫1在寫2而後1+2=3這樣的步驟.
只是推薦在寫或者說學習的過程當中多思考,多練習,而後慢慢優化提高.