BootStrap栅格系统的源码分析

容器

公共样式 container-fixed

【固定容器和流体容器的公共样式】

/** grid.less **/
.container-fixed(@gutter: @grid-gutter-width) {
    margin-left: auto;
    margin-right: auto;
    padding-left: floor((@gutter / 2)); // 槽宽的一半:即 30px / 2 = 15px
    padding-rigth: ceil((@gutter / 2));
    &:extend(.clearfix all) // 清除浮动,继承clearfix.less里面定义的clearfix混合
}

清除浮动 .clearfix

/** clearfix.less **/
// BootStrap
.clearfix(){
    &:before,
    &:after {
        content: " ";
        display: table; //  兼容性比较高
    }
    &:after {
        clear: both;
    }
}

【常见用来清除浮动的几种方式】

  1. 给浮动元素的父盒子添加伪元素,并利用伪元素来清除浮动

    .clearfix::after{
        content: "";
        dispaly: block;
        clear: both;
        visibility:hidden;
        height:0;
        zoom:1 // 解决ie6,7的浮动问题
    }
    
  2. 给浮动元素的父级盒子添加overflow:autooverflow:hidden(不推荐使用)

    overflow:auto=> 如果页面中需要出现滚动条可以使用

    overflow:hidden=> 页面不需要滚动条,没有使用position(超出的尺寸会被隐藏)可以使用

  3. 父级元素也浮动(了解)

  4. 给浮动的父元素添加display:table,将其变成表格(不推荐使用)

流体容器

盒子的width为auto

固定容器

阈值width
>= 1200【lg:大屏PC】1170
[ 992, 1200 ) 【md:中屏PC】970
[ 768, 992 ) 【sm:平板】750
<= 768【xs:手机】auto (流体容器)

width:100%width:auto的区别】

  • width:100%: 左右的padding是在两边另外加的
  • width:auto: 左右的padding是里面扣掉的

width:auto

在这里插入图片描述

width:100%

在这里插入图片描述

源码分析

【固定容器的样式】:

.container{
    // 公共样式
    .container-fixed(); 
    /**
       媒体查询:通过媒体查询,来设置不同屏幕尺寸下的网页宽度
    		阈值:
    			 @screen-sm-min : 768px
    			 @screen-md-min : 992px
     			 @screen-lg-min : 1200px
    		width:
    			@container-sm = 720px + @grid-gutter-width = 750px
    			@container-md = 940px + @grid-gutter-width = 970px
    			@container-lg = 1140px + @grid-gutter-width = 1170px
    **/
    @media (min-width: @screen-sm-min) { 
        width: @container-sm; // 750px
    }
    @media (min-width: @screen-md-min) { // 
        width: @container-md; // 970px
    }
    @media (min-width: @screen-lg-min) {
        width: @container-lg; // 1170px
    }
}

假设目前屏幕是 1300px前面的两条样式也会被读到,只不过是被最后一个满足条件的样式覆盖了

假设屏幕是 200px则这三条样式都不会被读到,因此此时就是用默认值:width: auto

栅格系统

栅格系统是通过一系列的行和列的组合来创建页面布局的。

行 & 列

.make-row

.make-row(@gutter: @grid-gutter-width){
    margin-left: ceil((@gutter / -2)); // 负槽宽的一半即: -15px
    margin-right: floor((@gutter / -2)); // 负槽宽的一半即: -15px
    &:extend(.clearfix all)
}

.列

.make-grid-columns();
// 默认 手机: xm
.make-grid(xs);
// 平板:sm
@media (min-width: @screen-sm-min) {
    .make-grid(sm);
}
// 中屏PC md
@media (min-width: @screen-md-min) {
    .make-grid(md);
}
// 大屏PC lg
@media (min-width: @screen-lg-min) {
    .make-grid(lg);
}

make-grid-columns()

列的第一步:给不同屏幕尺寸下的每一个都设置一个共同的样式:相对定位,列的最小高度,左右padding

/** make-grid-columns() 混合的内容**/
make-grid-columns(){
    .col(@index){
        @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
        .col((@index + 1), @item);
    }
    .col(@index, @list) when (@index =< @grid-columns) {
        @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
        .col((@index + 1), ~"@{list}, @{item}");
    }
    .col(@index, @list) when (@index > @grid-columns) {
        @{list} {
            position: relative; // 为了列排序做准备
            min-height: 1px;
            padding-left: ceil((@grid-gutter-width / 2));
            padding-right: floor((@grid-gutter-width / 2))
        }
    }
    .col(1);
}

在这里插入图片描述

.make-grid(xs);

列的第二步:根据屏幕不同的尺寸大小,来执行.make-grid(type)混合

.make-grid(xs);
// 平板:sm
@media (min-width: @screen-sm-min) {
    .make-grid(sm);
}
// 中屏PC md
@media (min-width: @screen-md-min) {
    .make-grid(md);
}
// 大屏PC lg
@media (min-width: @screen-lg-min) {
    .make-grid(lg);
}

【第 2 步】

.make-grid(@class){
    .float-grid-columns(@class); // 第 2.1 步
    .loop-grid-columns(@grid-columns, @class, width);  // 第 2.2 步
    .loop-grid-columns(@grid-columns, @class, pull);  // 第 2.3 步
    .loop-grid-columns(@grid-columns, @class, push);  // 第 2.3 步
    .loop-grid-columns(@grid-columns, @class, offset);  // 第 2.4 步
}

【第 2.1 步】

给每一个列都设置浮动

.float-grid-columns(@class) {
    .col(@index){
        @item: ~".col-@{class}-@{index}";
        .col((@index+1), @item);
    }
    .col(@index, @list) when (@index =< @grid-columns) {
        @item: ~".col-@{class}-@{index}";
        .col((@index+1), ~"@{list}, @{item}")
    }
    .col(@index, @list) when (@index > @grid-columns) {
        @{list} {
            float: left;
        }
    }
    .col(1)
}

编译后的结果:(加入当前设备是 xs)

.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4,
.col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8,
.col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12{
    float: left;
}

【第 2.2、2.3、2.4 入口】

 .loop-grid-columns(@grid-columns, @class, width);  // 第 2.2 步
 .loop-grid-columns(@grid-columns, @class, pull);  // 第 2.3 步
 .loop-grid-columns(@grid-columns, @class, push);  // 第 2.3 步
 .loop-grid-columns(@grid-columns, @class, offset);  // 第 2.4 步

// 2.2、 2.3、 2.4 入口
.loop-grid-columns(@index, @class, @type) when(@index >= 0) {
    // 相当于递归体(要被调用12次)
    .calc-grid-columns(@index, @class, @type);
    // 下一次循环
    .loop-grid-columns((@index-1), @class, @type)
}

【第 2.2 步】

/**根据列的个数设置对应的宽度 (作为递归体,要被调用12次)**/
.calc-grid-columns(@index, @class, @type) when (@type = width) and (@index > 0) {
    .col-@{class}-@{index}{
    	width: percentage((@index / @grid-columns));    
	}
}
.loop-grid-columns((@index-1), @class, @type)

假设这里的type为 xs:步骤2.2编译后的结果为:

.col-xs-12{
 width: 12/12;
}
.col-xs-12{
 width: 11/12;
}
...
.col-xs-1{
 width: 1/12;
}

栅格的组合就是通过less的递归来实现的

<div calss= "container">
 <div class="col-lg-10 col-md-6"></div>
 <div class="col-lg-2 col-md-6"></div>
</div>

【第 2.3 步】列排序(设置列的left和right)

.loop-grid-columns(@index, @class, @type) when(@index >= 0) {
 // 相当于递归体(要被调用12次)
 .calc-grid-columns(@index, @class, @type);
 // 下一次循环
 .loop-grid-columns((@index-1), @class, @type)
}
/**作为递归体,要被调用12次**/
.calc-grid-columns(@index, @class, @type) when (@type = push) and (@index > 0) {    
    .col-@{class}-push-@{index}{        
        left: percentage((@index / @grid-columns))    
     }
}
/**执行一次**/
.cal-grid-columns(@index, @class, @type) when (@type = push) and (@index = 0) {
    .col-@{class}-push-0 {
        left: auto;
    }
}
.loop-grid-columns((@index-1), @class, @type)
  • push => left, 且 index=0时, left:auto
  • pull => right, 且 index=0时, right: 0
/**作为递归体,要被调用12次**/
.calc-grid-columns(@index, @class, @type) when (@type = pull) and (@index > 0) {    
    .col-@{class}-pull-@{index}{        
        right: percentage((@index / @grid-columns))    
     }
}
/**执行一次**/
.cal-grid-columns(@index, @class, @type) when (@type = pull) and (@index = 0) {
    .col-@{class}-pull-0 {
        right: 0;
    }
}
.loop-grid-columns((@index-1), @class, @type)

2.3编译的结果:

/**push**/
.col-xs-push-12{
 left: 12/12;
}
.col-xs-push-12{
 left: 11/12;
}
...
.col-xs-push-1{
 left: 1/12;
}
//注意
.col-xs-push-0{
 left: auto;
}
/**pull**/
.col-xs-pull-12{
 right: 12/12;
}
.col-xs-pull-12{
 right: 11/12;
}
...
.col-xs-pull-1{
 right: 1/12;
}
//注意
.col-xs-pull-0{
 right: 0;
}

【第 2.4 步】列偏移

.loop-grid-columns(@index, @class, @type) when(@index >= 0) {
 // 相当于递归体(要被调用12次)
 .calc-grid-columns(@index, @class, @type);
 // 下一次循环
 .loop-grid-columns((@index-1), @class, @type)
}
// 执行12次
.cal-grid-columns(@index, @class, @type) when (@type = offset){
    .col-@{class}-offset-@{index}{
        margin-left: percentage((@index / @grid-columns))
    }
}
.loop-grid-columns((@index-1), @class, @type)

编译结果:

/**offset**/
.col-xs-offset-12{
  margin-left: 12/12;
}
.col-xs-offset-12{
  margin-left: 11/12;
}
...
.col-xs-offset-1{
  margin-left: 1/12;
}
.col-xs-offset-0{
 margin-left: 0;
}

栅格盒模型的设计精妙之处

在这里插入图片描述

定制化:p13

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值