bootstrap的grid system由3部分组成:css
container有2种。container
: 固定宽度且水平居中; container-fluid
: 满屏。
row占满整个container, 一行能够包括12个column。
column有4种类型:lg
, md
, sm
, xs
,分别对应着4种设备屏幕大小。html
learn morebootstrap
首先,咱们先用bower来安装bootstrap-sass, 咱们从bootstrap的sass源码来分析。segmentfault
bower install bootstrap-sass --save
grid system主要涉及3个文件。_grid.scss
, mixin/_grid.scss
, mixin/_gridframework.scss
。sass
css.container { @include container-fixed; @media (min-width: $screen-sm-min) { width: $container-sm; } // more }
@include
引入了一个mixin:container-fixed
, 他设置了margin-left
和margin-right
都为auto
。
而后经过media query来设定不一样的width
。
这样的话,就可使得.container
水平居中了。oop
$screen-sm-min
4种设备屏幕大小的breakpoint之一(能够在_variables.scss
)找到。ui
$screen-xs: 480px !default; // 手机 $screen-sm: 768px !default; // 平板 $screen-md: 992 !default; // 桌面计算机 $screen-lg: 1200 !default;
css.row { @include make-row; } @mixin make-row($gutter: $grid-gutter-width) { margin-left: ($gutter / -2); }
make-row
设置了margin-left/right
为负值,这样就能够把row的width变大。code
@include make-grid-columns;
@mixin make-grid-columns($i: 1, $list: ".col-xs-#{$i}, .col-sm-#{$i}, .col-md-#{$i}, .col-lg-#{$i}") { @for $i from (1 + 1) through $grid-columns { $list: "#{$list}, .col-xs-#{$i}, .col-sm-#{$i}, .col-md-#{$i}, .col-lg-#{$i}"; } #{$list} { position: relative; padding-left: ($grid-gutter-width / 2); padding-right: ($grid-gutter-width / 2); } } //上面的scss会编译成下面的css: .col-[xs,sm,md,lg]-[1-9] { position: realative; padding-left: 15px; }
#{$i}
的做用是把$i
字符串转换成变量。dochtm
在for循环中,为何不从1开始呢?
由于$list
每次循环后都要加上原来的$list
(也就是+=
),而且$list
的初始值不能为空,因此他的初始值就是1(col-sm-1
)。开发
position: relative
在这里的做用是什么呢?
在下面,咱们会讲到每一个column都有一个width, 他的值是percentage的。根据doc, 百分比是相对于该元素的containning block.
但我以为他的做用是为了他的children(position: absolute
)能够更好的定位。
css// 建立xs columns @include make-grid(xs); // 给column设置float属性 @mixin make-grid($class) { @include float-grid-columns($class); } // 这个跟上面的make-grid-columns差很少 @mixin float-grid-columns($class, $i: 1, $list: ".col-#{$class}-#{$i}") { @for $i from (1 + 1) through $grid-columns { $list: "#{$list}, .col-#{$class}-#{$i}"; } #{$list} { float: left; } }
这里我有个疑问:既然
float-grid-columns
的做用是让每种column都浮动。那么他为何不写在make-grid-columns
里面呢?那里不是都写column的公共样式吗?
@mixin make-grid($class) { // 传了个width参数 @include loop-grid-columns($grid-columns, $class, width); } // 起到一个循环的做用 @mixin loop-grid-columns($columns, $class, $type) { @for $i from 0 through $columns { @include calc-grid-column($i, $class, $type); } } @mixin calc-grid-column($index, $class, $type) { @if ($type == width) and ($index > 0) { .col-#{$class}-#{$index} { width: percentage(($index / $grid-columns)); } }
当我没设置box-sizing: border-box
的时候,12个column不会恰好占满的一行。
由于有padding
, margin
的存在。
但若是设置以后,margin
就属于width
了。这样就刚恰好。
这个也是bootstrap grid system可以平均分红12列的缘由。
他会设置column的左边和他的containning block的距离
scss// 若是index不为0,如2。因此left: 2 / 12. @if ($type == push) and ($index > 0) { .col-#{$class}-push-#{$index} { left: percentage(($index / $grid-columns)); } } @if ($type == push) and ($index == 0) { .col-#{$class}-push-0 { left: auto; } }
这个也会使得column偏移。那他和上面的push有什么不一样呢?
scss@if ($type == offset) { .col-#{$class}-offset-#{$index} { margin-left: percentage(($index / $grid-columns)); } }
由于offset设置的是margin-left
,因此他是占据空间的。
html// #column2在这里会挤压到另外一行 <div class="col-lg-2 col-lg-offset-10" id="column1"></div> <div class="col-lg-4" id="column2"></div>
html// #column2不会被挤压到另外一行 <div class="col-lg-2 col-lg-push-10" id="column1"></div> <div class="col-lg-4" id="column2"></div>
box-sizing: border-box
来平均分红12列,sass
来迅速开发