Less在Bootstrap3中解析過程(詳細)

    前言
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這樣的步驟.

    只是推薦在寫或者說學習的過程當中多思考,多練習,而後慢慢優化提高.

相關文章
相關標籤/搜索