bootstrap栅格系统
bootstrap栅格系统是bootstrap的核心以及精髓所在
一、容器
- 1.流体容器
- 流体容器宽度为100%(即占当前视口的宽度)
- 2.固定容器
大于等于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. 栅格组合
利用栅格系统在不同设备状态下页面布局有不同的提现
例如
<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值
例如
<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的值
例如
<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设备上的显示与隐藏
<!--该元素在视口小于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:槽宽
/*@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实际中的代码
.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混合中的代码
.make-row(@gutter: @grid-gutter-width) {
margin-left: ceil((@gutter / -2));
margin-right: floor((@gutter / -2));
&:extend(.clearfix all);
}
- 行元素样式在less中的代码
.row {
.make-row();
}
- 列元素样式在less中实际的代码
// 列的默认样式
.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.核心代码
- 列元素样式的初步实现
//列元素的默认样式实现
.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);
}
- 列元素具体样式的实现
.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);
}
- 写入所有列的默认值
//@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);
}
- 设置宽度列排列和列偏移的入口代码
//由于当前状态下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);
}
- 规定个个列的宽度
//当@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));//将数值转换为百分比
//}
- 列排列控制
//当@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;
}
}
- 列偏移控制
//当@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);
//}
}
原文链接.