栅格系统源码解读

bootstrap3 | 本篇文章共1.8k字,预计阅读10分钟

栅格系统文件结构

  • variables.less
  • gird.less
  • mixins
    • clearfix.less
    • gird.less
    • gird-framework.less

分析 gird.less 中的内容

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//
// Grid system

// Container widths
//
// Set the container width, and override it for fixed navbars in media queries.

.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;
}
}


// Fluid container
//
// Utilizes the mixin meant for fixed width containers, but without any defined
// width for fluid, full width layouts.

.container-fluid {
.container-fixed();
}


// Row
//
// Rows contain and clear the floats of your columns.

.row {
.make-row();
}


// Columns
//
// Common styles for small and large grid columns

.make-grid-columns();


// Extra small grid
//
// Columns, offsets, pushes, and pulls for extra small devices like
// smartphones.

.make-grid(xs);


// Small grid
//
// Columns, offsets, pushes, and pulls for the small device range, from phones
// to tablets.

@media (min-width: @screen-sm-min) {
.make-grid(sm);
}


// Medium grid
//
// Columns, offsets, pushes, and pulls for the desktop device range.

@media (min-width: @screen-md-min) {
.make-grid(md);
}


// Large grid
//
// Columns, offsets, pushes, and pulls for the large desktop device range.

@media (min-width: @screen-lg-min) {
.make-grid(lg);
}

guid.less是栅格系统的主要结构文件,主要分4个方面

  1. container width
  2. Fluid container
  3. Row
  4. Columns
    • make-grid-columns(); 不同媒体查询下列的公共样式
    • .make-grid(xs); 移动端设备屏幕尺寸 <768px
    • .make-grid(sm); 平板设备屏幕尺寸 >=768px
    • .make-grid(md); 中屏pc屏幕尺寸 >=992px
    • .make-grid(lg); 大屏pc 屏幕尺寸>=1200px

容器

.container.fluid container 的相同之处:拥有共同的混合.container-fixed()

1
2
3
4
5
6
7
8
9
10
.clearfix() {
&:before,
&:after {
content: " "; // 1
display: table; // 2
}
&:after {
clear: both;
}
}
1
2
3
4
5
6
7
.container-fixed(@gutter: @grid-gutter-width) {
margin-right: auto;
margin-left: auto; // @grid-gutter-width:30px;
padding-left: floor((@gutter / 2)); // 15px;
padding-right: ceil((@gutter / 2)); // 15px
&:extend(.clearfix all); // 混合中的清除浮动继承
}

固体容器和流体容器左右外边距都为auto,这意味着2个容器都是水平居中的

固体容器和流体容器都拥有相同的左右、内边距以及前后的清除浮动

这2种容器都是响应式的栅格系统布局,不同之处在于容器的宽度,固体容器则使用媒体查询,在不同尺寸的屏幕中有不同的容器宽度设定,而流体容器则自适应屏幕的宽度,宽度永远保持在视口宽度的100%

.fluid container 流体容器

width:auto

.container固体容器的特别之处,不同的媒体查询下有不同的容器宽度

1
2
3
4
5
6
7
8
9
@media (min-width:768px) {   // 设备屏幕尺寸 >=768px
width: 750px; // 720px + @grid-gutter-width
}
@media (min-width:992px) { // 设备屏幕尺寸 >=992px
width:970px; // 940px + @grid-gutter-width
}
@media (min-width: 1200px) { //设备屏幕尺寸 >=1200px
width: 1170px; // 1140px + @grid-gutter-width
}

Row 行

1
2
3
4
5
6
7
8
9
10
11
.clearfix() {
&:before,
&:after {
content: " "; // 1
display: table; // 2
}
&:after {
clear: both;
}
}

1
2
3
4
5
.make-row(@gutter: @grid-gutter-width) {
margin-left:-15px;
margin-right:-15px;
&:extend(.clearfix all); // 继承清除浮动样式
}

行拥有左右的负边距以及前后的清除浮动

Column 列

.make-grid-columns() 不同媒体查询下列的公共样式

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
.make-grid-columns() {
.col(@index) {
@item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
.col((@index + 1), @item);
} // .col(2,".col-xs-1,-col-sm-1,.col-md-1,.clo-lg-1");

.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(3,".col-xs-1,-col-sm-1,.col-md-1,.clo-lg-1",".col-xs-2,.col-sm-2,.col-md-2,.col-lg-2",)

.col(@index, @list) when (@index > @grid-columns) {
@{list} {
position: relative;
// Prevent columns from collapsing when empty
min-height: 1px;
// Inner gutter via padding
padding-left: ceil((@grid-gutter-width / 2));
padding-right: floor((@grid-gutter-width / 2));
}
}
.col(1);
}

// .col-xs-1,-col-sm-1,.col-md-1,.clo-lg-1,
.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,
.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,
.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,
......
.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,
.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12 {

position: relative;
min-height: 1px;
padding-left:15px;
padding-right:15px;

}

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
.float-grid-columns(@class) {
.col(@index) { // initial
@item: ~".col-@{class}-@{index}";
.col((@index + 1), @item);
}
.col(@index, @list) when (@index =< @grid-columns) { // general
@item: ~".col-@{class}-@{index}";
.col((@index + 1), ~"@{list}, @{item}");
}
.col(@index, @list) when (@index > @grid-columns) { // terminal
@{list} {
float: left;
}
}
.col(1); // kickstart it
}

// .col-xs-1,-col-sm-1,.col-md-1,.clo-lg-1,
.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,
.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,
.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,
......
.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,
.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12 {

float:left

}

公共样式:相对定位,最小行高,左、右内边距,左浮动

移动端列的宽度、列排序、偏移

1
2
3
4
5
6
7
8
9
10
11
12
13
.make-grid(@class) {
.float-grid-columns(@class);
.loop-grid-columns(@grid-columns, @class, width);
.loop-grid-columns(@grid-columns, @class, pull);
.loop-grid-columns(@grid-columns, @class, push);
.loop-grid-columns(@grid-columns, @class, offset);
}

.loop-grid-columns(@index, @class, @type) when (@index >= 0) {
.calc-grid-column(@index, @class, @type);
// next iteration
.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
34
.make-grid(@class) {
.float-grid-columns(@class);
.loop-grid-columns(@grid-columns, @class, width);

.loop-grid-columns(@index, @class, @type) when (@index >= 0) {
.calc-grid-column(@index, @class, @type);
// next iteration 执行完一次后,@index-1再次执行
.loop-grid-columns((@index - 1), @class, @type);
// 该处可以看出初始值@index=@gird-columns=12
// @class即是设备尺寸大小
}
.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)
}
.col-xs-11 {
width: percentage(11/12)
}
.col-xs-10 {
width: percentage(10/12)
}
......
.col-xs-2 {
width: percentage(2/12)
}
.col-xs-1 {
width: percentage(1/12)
}

列的偏移

当@type=offset时,推算列的偏移

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.col-xs-offset-12 {
margin-left: percentage(12/12)
}
.col-xs-offset-11 {
margin-left: percentage(11/12)
}
.col-xs-offset-10 {
margin-left: percentage(10/12)
}
......
.col-xs-offset-2 {
margin-left: percentage(2/12)
}
.col-xs-offset-1 {
margin-left: percentage(1/12)
}
.col-xs-offset-0 {
margin-left: 0
}
列的排序
push (left)

当@type=push时,推算列的排序,决定left值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.col-xs-push-12 {
left: percentage(12/12)
}
.col-xs-push-11 {
left: percentage(11/12)
}
.col-xs-push-10 {
left: percentage(10/12)
}
......
.col-xs-push-2 {
left: percentage(2/12)
}
.col-xs-push-1 {
left: percentage(1/12)
}
.col-xs-push-0 {
left: auto
}
pull (right)

当@type=pull时,推算列的排序,决定right值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 .col-xs-pull-12 {
right: percentage(12/12)
}
.col-xs-pull-11 {
right: percentage(11/12)
}
.col-xs-pull-10 {
right: percentage(10/12)
}
......
.col-xs-pull-2 {
right: percentage(2/12)
}
.col-xs-pull-1 {
right: percentage(1/12)
}
.col-xs-pull-0 {
right:atuo
}

其他设备

当@class=sm,md.lg时,会推算出不同设备的宽度、列偏移、列排序。

本文作者: moofing

本文链接: https://moofing.gitee.io/posts/eacda123.html

版权声明: 本文采用 CC BY-NC-SA 4.0进行许可,转载或引用时请遵守该协议