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这样的步骤.

    只是推荐在写或者说学习的过程当中多思考,多练习,而后慢慢优化提高.

相关文章
相关标签/搜索