Fork me on GitHub

css笔记-bootstrap栅格系统分析

bootstrap栅格系统

bootstrap栅格系统是bootstrap的核心以及精髓所在

一、容器

  • 1.流体容器
    • 流体容器宽度为100%(即占当前视口的宽度)
  • 2.固定容器
阈值 width
大于等于1200(lg 大屏pc) 1170(1140+槽宽)
大于等于992(md 中屏pc)小于1200 970(940+槽宽)
大于等于768(sm 平板)小于992 750(720+槽宽)
小于768(xs 移动手机) auto

二、栅格系统的应用

1. 栅格参数

类别 超小屏幕 手机 (<768px) 小屏幕 平板 (≥768px) 中等屏幕 桌面显示器 (≥992px) 大屏幕 大桌面显示器 (≥1200px)
栅格系统行 总是水平排列 开始是堆叠在一起的,当大于这些阈值时将变为水平排列 开始是堆叠在一起的,当大于这些阈值时将变为水平排列 开始是堆叠在一起的,当大于这些阈值时将变为水平排列
.container 最大宽度 None 750px 970px 1170px
类前缀 .col-xs- .col-sm- .col-md- .col-lg-
列数(column) 12 12 12 12
最大列宽 自动 ~62px ~81px ~97px
槽(gutter)宽 30px (每列左右均有 15px) 30px 30px 30px
可嵌套
偏移(Offsets)
列排序

2. 栅格组合

利用栅格系统在不同设备状态下页面布局有不同的提现

例如

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

3. 列偏移和列排序

列排序

通过使用 .col-xx-push-y和 .col-xx-pull-y类就可以很容易的改变列(column)的顺序。
实际上在控制元素left值

例如

1
2
3
4
<div class="row">
<div class="col-md-9 col-md-push-3">.col-md-9 .col-md-push-3</div>
<div class="col-md-3 col-md-pull-9">.col-md-3 .col-md-pull-9</div>
</div>

列偏移

.col-xx-offset-y 类可以将列向右侧偏移
实际上在控制元素margin-left的值

例如

1
2
3
4
<div class="row">
<div class="col-md-9 col-md-push-3">.col-md-9 .col-md-push-3</div>
<div class="col-md-3 col-md-pull-9">.col-md-3 .col-md-pull-9</div>
</div>

4. 响应式工具的使用

利用.visible-xx 和 .hidden-xx 控制元素在该xx设备上的显示与隐藏

1
2
3
4
5
6
7
8
<!--该元素在视口小于768px的情况下隐藏-->
<div class="jumbotron hidden-xs">
<h1>Hello, world!</h1>
</div>
<!--该元素在视口小于768px的情况下显示-->
<div class="jumbotron visible-xs">
<h1>Hello, world!</h1>
</div>

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

容器两边具有15px的padding

目标 规则
两边具有15px的padding
两边具有-15px的margin
  • 为了维护槽宽的规则,
    • 列两边必须得要15px的padding
  • 为了能使列嵌套行
    • 行两边必须要有-15px的margin
  • 为了让容器可以包裹住行
    • 容器两边必须要有15px的padding

三、栅格系统源码解析

1.基本实现的流程

  • 固定和流体容器的公共样式在less混合中的代码

注:@grid-gutter-widt:槽宽

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*@gutter在bootstrap里默认为30px*/
.container-fixed(@gutter: @grid-gutter-width) {
margin-right: auto;
margin-left: auto;
padding-left: floor((@gutter / 2)); //向下取整 (此时默认值为15px)
padding-right: ceil((@gutter / 2)); //向上取整 (此时默认值为15px)
&:extend(.clearfix all); //继承清除浮动的样式
}
/*.clearfix的样式*/
.clearfix() {
&:before,
&:after {
content: " "; // 1
display: table; // 2
}
&:after {
clear: both;
}
}
  • 固定容器和流体容器的样式在less实际中的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.container {
.container-fixed();//继承默认样式
//利用媒体查询判断当前应当采用的宽度
//移动优先!
@media (min-width: @screen-sm-min) {
width: @container-sm;
}
@media (min-width: @screen-md-min) {
width: @container-md;
}
@media (min-width: @screen-lg-min) {
width: @container-lg;
}
}
//流体容器
.container-fluid {
.container-fixed();
}
  • 行元素默认样式在less混合中的代码
1
2
3
4
5
.make-row(@gutter: @grid-gutter-width) {
margin-left: ceil((@gutter / -2));
margin-right: floor((@gutter / -2));
&:extend(.clearfix all);
}
  • 行元素样式在less中的代码
1
2
3
.row {
.make-row();
}
  • 列元素样式在less中实际的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 列的默认样式
.make-grid-columns();
// 判断当前视口的大小采用不同的样式
//移动优先!
.make-grid(xs);
@media (min-width: @screen-sm-min) {
.make-grid(sm);
}
@media (min-width: @screen-md-min) {
.make-grid(md);
}
@media (min-width: @screen-lg-min) {
.make-grid(lg);
}

2.核心代码

  • 列元素样式的初步实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//列元素的默认样式实现
.make-grid-columns() {
//此时@index为1
.col(@index) {
@item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
// @item: ~".col-xs-1, .col-sm-1, .col-md-1, .col-lg-1";//不编译
.col((@index + 1), @item);
// .col(2, ~".col-xs-1, .col-sm-1, .col-md-1, .col-lg-1");
}
//利用递归循环创建所有列元素的样式
//@grid-columns默认为12 @list为@item的集合
.col(@index, @list) when (@index =< @grid-columns) {
//当@index=<12时执行以下代码
@item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
//此时index为2则
//@item: ~".col-xs-2, .col-sm-2, .col-md-2, .col-lg-2";
.col(3, ~".col-xs-1, .col-sm-1, .col-md-1,
.col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2");
//因为3<=12则继续执行递归
//由此可以当递归完成时
@list:.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1,
.col-xs-2, .col-sm-2, .col-md-2, .col-lg-2,
...
.col-xs-12, .col-sm-12, .col-md-12, .col-lg-12
}
//当@index>12时执行下面的代码
//以上代码完成时递归完成时index>13
//执行以下代码
.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));
}
//由于此时@list状态已经完成则以下代码为
//.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1,
//.col-xs-2, .col-sm-2, .col-md-2, .col-lg-2,
//...
//.col-xs-12, .col-sm-12, .col-md-12, .col-lg-12{
// position: relative;
//min-height: 1px;
//padding-left: ceil((@grid-gutter-width / 2));
//padding-right: floor((@grid-gutter-width / 2));
//}
//完成所有列的状态的默认值
//及.make-grid-columns()完成所有列的状态的默认样式
}
//传入默认值1
.col(1);
}
  • 列元素具体样式的实现
1
2
3
4
5
6
7
8
9
10
11
12
13
.make-grid(@class) {
//1.写入所有列的默认值
.float-grid-columns(@class);
//2.规定个个列的宽度
.loop-grid-columns(@grid-columns, @class, width);
//3.列排列控制的是目标元素的left或right的值由于值不能为0所以分开操作
//3.1列向右排列
.loop-grid-columns(@grid-columns, @class, pull);
//3.2列向右排列
.loop-grid-columns(@grid-columns, @class, push);
//4.设置列偏移 控制的是margin-left;
.loop-grid-columns(@grid-columns, @class, offset);
}
  • 写入所有列的默认值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//@class 为 xs,sm,md,lg
//下面的代码里@class的值设为xs
.float-grid-columns(@class) {
.col(@index) {
@item: ~".col-@{class}-@{index}";
//@item:~".col-xs-1";
.col((@index + 1), @item);
//.col(2, ~".col-xs-1");
}
//同样利用递归循环index至12完成对每个@class列的属性
.col(@index, @list) when (@index =< @grid-columns) {
@item: ~".col-@{class}-@{index}";
//@item: ~".col-xs-2";
.col((@index + 1), ~"@{list}, @{item}");
//.col(3, ~".col-xs-1, .col-xs-2");
//递归完成时@list为:
//.col-xs-1, .col-xs-2,...,.col-xs-12
}
//当递归完成时执行下面的代码
.col(@index, @list) when (@index > @grid-columns) {
@{list} {
float: left;
}
//以上代码及为
//.col-xs-1, .col-xs-2,...,.col-xs-12{
//float: left;
//}
//}
//填入@index的默认值1
.col(1);
}
  • 设置宽度列排列和列偏移的入口代码
1
2
3
4
5
6
//由于当前状态下index为12则从12开始递归至0
//@index索引 @class栅格类 @type 要进行操作的属性
.loop-grid-columns(@index, @class, @type) when (@index >= 0) {
.calc-grid-column(@index, @class, @type);
.loop-grid-columns((@index - 1), @class, @type);
}
  • 规定个个列的宽度
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//当@type = width时执行的代码
.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {
.col-@{class}-@{index} {
width: percentage((@index / @grid-columns));
}
}
//以上代码可以表示为
.loop-grid-columns(@index, @class, @type) when (@index >= 0) {
.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {
.col-@{class}-@{index} {
width: percentage((@index / @grid-columns));
}
//.col-xs-12 {
// width: percentage(12/12));//将数值转换为百分比
//}
}
.loop-grid-columns((@index - 1), @class, @type);
//再次执行
//.col-xs-11 {
//width: percentage(11/12));//将数值转换为百分比
//}
}
//递归完成后得到的是
//.col-xs-12 {
// width: percentage(12/12));//将数值转换为百分比
//}
//.col-xs-11 {
// width: percentage(11/12));//将数值转换为百分比
//}....
//.col-xs-1 {
// width: percentage(1/12));//将数值转换为百分比
//}
  • 列排列控制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//当@type = push执行如下代码
//@index的递减在.loop-grid-columns(@index, @class, @type) when (@index >= 0) 环境下已经实现
.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {
.col-@{class}-push-@{index} {
left: percentage((@index / @grid-columns));
}
//以上代码生成的值为
//.col-xs-push-12 {
//left: percentage(12/12);
//}
//.col-xs-push-11 {
//left: percentage(11/12);
//}....
//.col-xs-push-1 {
//left: percentage(1/12);
//}
}
//当index为0时执行下面的代码
.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {
.col-@{class}-push-0 {
left: auto;
}
//.col-xs-push-0 {
//left: auto;
//}
}
//向左偏移生成模式与向右相同
.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {
.col-@{class}-pull-@{index} {
right: percentage((@index / @grid-columns));
}
}
.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {
.col-@{class}-pull-0 {
right: auto;
}
}
  • 列偏移控制
1
2
3
4
5
6
7
8
9
10
11
12
13
//当@type = offset时执行如下代码
.calc-grid-column(@index, @class, @type) when (@type = offset) {
.col-@{class}-offset-@{index} {
margin-left: percentage((@index / @grid-columns));//值转换为百分比
}
//运行结果
//.col-xs-offset-12 {
//margin-left: percentage(12/12);
//}...
//.col-xs-offset-1 {
//margin-left: perc/entage(1/12);
//}
}