栅格化-中【less源码分析】
栅格化-中【less源码分析】
接“栅格化-上【12列布局和预定义类】”,对bootstrap中栅格化部分less源码进行分析:
源码主要位于三个文件中:
/less/grid.less
/less/mixins/grid.less
/less/mxins/grid-framework.less
less/grid.less是负责编译css的:
grid.less
// // 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); }
那么在这个源码中,都有哪些东西呢 ,其实东西不多,接下来我们来一一攻破。
在grid.less中有下边的几个变量和混合:
变量:@screen-sm-min、 @screen-md-min、 @screen-lg-min、 @container-sm、 @container-md、@container-lg
混合:.container-fixed()、 .make-row()、 .make-grid-columns()、 .make-grid(xs)、 .make-grid(sm)、 .make-grid(md)、 .make-grid(lg)
类:.container、 .container-fluid、 .row
首先,变量的第一组@screen-sm-min、 @screen-md-min、 @screen-lg-min定义的是相对应栅格模式的最小宽度,用于媒体查询的。
变量的第二组,是第一组媒体查询相应的width属性赋值,两组变量组合来控制.container在不同屏幕范围下的最大宽度。
混合:
第一个 .container-fixed();
这个混合同样是在.container和.container-fluid两个样式里面出现的,那我们来查找一下他在哪,内容都有什么。
它在less/mixins/grid.less中,内容如下:
.container-fixed()
// Centered container element .container-fixed(@gutter: @grid-gutter-width) { //定义了一个@gutter参数,默认值是@grid-gutter-width margin-right: auto; margin-left: auto; //左右margin都设置为auto padding-left: (@gutter / 2); padding-right: (@gutter / 2);//左右padding都设置为@gutter的一半 &:extend(.clearfix all); //继承.clearfix下的所有伪元素的样式 }
@grid-gutter-width图解:
&:extend(.clearfix all)图解:
看到这里聪明的你一定明白了这个样式的作用,没错,它就是为栅格化容器类 .container和.container-fluid添加基础样式用的,同时继承了清除浮动的样式。
第二个:.make-row();
.make-row
// Creates a wrapper for a series of columns .make-row(@gutter: @grid-gutter-width) { margin-left: (@gutter / -2); margin-right: (@gutter / -2); &:extend(.clearfix all); }
同理,你知道它是干嘛的了吧,如果这里没有反应过来,就回去翻一翻"栅格化-上【12列布局和预定义类】"中最后的补充部分。
第三个: .make-grid-columns();
它位于这个文件/less/mxins/grid-framework.less中:
它的作用是循环,为60种情况类名添加基础样式,注释中有详述:
.make-grid-columns()
.make-grid-columns() { // Common styles for all sizes of grid columns, widths 1-12 //这里是循环,当@index = 1的时候,声明变量@item等于一个个字符串,字符串格式就是列出.col-xx-@{index},以@{name}这种插值的形式引用变量@index,拼出".col-xs-1, .col-sm-1, .col-md-1, .col-lg-1"这样的几个类名,然后让@index+1并将其与@item字符串传入.col(@index,@list)作为参数,走下边的循环。 .col(@index) when (@index = 1) { // initial @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}"; .col((@index + 1), @item); } //这里的循环是,当@index =< 12的时候,让@item接收每次的@index变化,并拼接成~"@{list}, @{item}"这样的形式,中间的','就是用来拼接类名,走css并列选择器的语法,这里拼接结束之后,@item就具有了所有.col-xx-x形式的类名, 12*4 = 60 60个类名。 .col(@index, @list) when (@index =< @grid-columns) { // general; "=<" isn't a typo @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}"; .col((@index + 1), ~"@{list}, @{item}"); } //这里的循环是,当@item > 12的时候,为之前存好的60个类名统一添加基础样式,使用@{list}取到传入参数@list中的所有类选择器的字符串,然后为他们添加基础样式 .col(@index, @list) when (@index > @grid-columns) { // terminal @{list} { //这里的相对定位是为了.col-xx-push/pull-x准备的,这两个推和拉可以用来做列排序,原理走的是css相对定位left和right偏移 position: relative; // Prevent columns from collapsing when empty min-height: 1px; // Inner gutter via padding padding-left: (@grid-gutter-width / 2); padding-right: (@grid-gutter-width / 2); } } //开始循环的触发点 .col(1); // kickstart it }
第四个,这是一组 .make-grid(xs)、 .make-grid(sm)、 .make-grid(md)、 .make-grid(lg)
同样也是位于/less/mxins/grid-framework.less中:
作用:循环为参数中指定的@class设置float样式、基础的width、push(left)、pull(right)、offset(margin-left)
.make-grid代码:
.make-grid(@class)
//创建栅格化样式类,这里是为手动指定样式类型 xs、sm、md、lg和占用列数-x的样式类添加样式。 //传入的参数是样式类型,执行的是.float-grid-columns和.loop-grid-columns操作, //为每一个指定的'.col-md-4'之类的样式类添加了浮动和width //为每一个指定的'.col-md-offset-4'之类的样式类添加了margin-left //为每一个指定的'.col-md-push-4'之类的样式类添加了left //为每一个指定的'.col-md-pull-4'之类的样式类添加了right //这里注意'.col-md-offset-4'、'.col-md-push-4'、'.col-md-pull-4'都没有width属性,所以不能单独使用,要配合'.col-md-4'使用 // Create grid for specific class .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); }
这里引用了 .float-grid-columns和.loop-grid-columns
.float-grid-columns添加浮动,代码:
.float-grid-column(@class)
//这个循环原理和make-grid-columus是一样的,只是,它和make相比多了一个@class的参数,这里的@class参数是接收 xs、sm、md、lg这些col的类型的,调用的位置是在/less/grid.less文件中,make-grid(xx)调用 /* .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); } */ .float-grid-columns(@class) { .col(@index) when (@index = 1) { // 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 }
.loop-grid-columns循环(12~1)执行计算操作:
.loop-grid-columns
//这个循环控制当@index参数大于0的情况下执行calc-grid-column 每次@index减1。 // Basic looping in LESS .loop-grid-columns(@index, @class, @type) when (@index >= 0) { .calc-grid-column(@index, @class, @type); // next iteration .loop-grid-columns((@index - 1), @class, @type); }
这里是循环的逻辑,实际执行的是计算(这里才是赋值width、left、right、margin-left)的混合:
.calc-grid-column(@index, @class, @type)代码:
.calc-grid-column
//这里没有做循环的迭代,迭代是放在loop-grid-columns中的,calc的调用也是在loop中的。 //@type 规定了四个类型,width、push、pull、offset //percentage是less的数学函数,可以将浮点数转化为百分比字符串。 //所有的值位置都设置为(@index / @grid-columns),也就是当前列数/总列数(x/12) //width类型:走的是默认的宽度设置,为指定的@class添加width属性 .calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) { .col-@{class}-@{index} { width: percentage((@index / @grid-columns)); } } //push类型:走的是定位-推设置,为指定的@class添加left左偏移,左偏移向右推。 .calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) { .col-@{class}-push-@{index} { left: percentage((@index / @grid-columns)); } } .calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) { .col-@{class}-push-0 { left: auto; } } //pull类型:走的是定位-拉设置,为指定的@class添加right右偏移,右偏移向左拉。 .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; } } //offset类型:走的是偏移设置,为指定的@class添加margin-left,影响后续元素位置。 .calc-grid-column(@index, @class, @type) when (@type = offset) { .col-@{class}-offset-@{index} { margin-left: percentage((@index / @grid-columns)); } }
上面所用用到的@class指的是xs、sm、md、lg,所有的@index 指的是当前列数(1~12),
@grid-columns是实现variables.less中指定好的列数,值是12
源码的解析到这告一段落,根据less源码部分编译的css源码如下,也就是之前提到的1585~2251行的源码:
栅格化css源码
.container { padding-right: 15px; padding-left: 15px; margin-right: auto; margin-left: auto; } @media (min-width: 768px) { .container { width: 750px; } } @media (min-width: 992px) { .container { width: 970px; } } @media (min-width: 1200px) { .container { width: 1170px; } } .container-fluid { padding-right: 15px; padding-left: 15px; margin-right: auto; margin-left: auto; } .row { margin-right: -15px; margin-left: -15px; } .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-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .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-right: 15px; padding-left: 15px; } .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; } .col-xs-12 { width: 100%; } .col-xs-11 { width: 91.66666667%; } .col-xs-10 { width: 83.33333333%; } .col-xs-9 { width: 75%; } .col-xs-8 { width: 66.66666667%; } .col-xs-7 { width: 58.33333333%; } .col-xs-6 { width: 50%; } .col-xs-5 { width: 41.66666667%; } .col-xs-4 { width: 33.33333333%; } .col-xs-3 { width: 25%; } .col-xs-2 { width: 16.66666667%; } .col-xs-1 { width: 8.33333333%; } .col-xs-pull-12 { right: 100%; } .col-xs-pull-11 { right: 91.66666667%; } .col-xs-pull-10 { right: 83.33333333%; } .col-xs-pull-9 { right: 75%; } .col-xs-pull-8 { right: 66.66666667%; } .col-xs-pull-7 { right: 58.33333333%; } .col-xs-pull-6 { right: 50%; } .col-xs-pull-5 { right: 41.66666667%; } .col-xs-pull-4 { right: 33.33333333%; } .col-xs-pull-3 { right: 25%; } .col-xs-pull-2 { right: 16.66666667%; } .col-xs-pull-1 { right: 8.33333333%; } .col-xs-pull-0 { right: auto; } .col-xs-push-12 { left: 100%; } .col-xs-push-11 { left: 91.66666667%; } .col-xs-push-10 { left: 83.33333333%; } .col-xs-push-9 { left: 75%; } .col-xs-push-8 { left: 66.66666667%; } .col-xs-push-7 { left: 58.33333333%; } .col-xs-push-6 { left: 50%; } .col-xs-push-5 { left: 41.66666667%; } .col-xs-push-4 { left: 33.33333333%; } .col-xs-push-3 { left: 25%; } .col-xs-push-2 { left: 16.66666667%; } .col-xs-push-1 { left: 8.33333333%; } .col-xs-push-0 { left: auto; } .col-xs-offset-12 { margin-left: 100%; } .col-xs-offset-11 { margin-left: 91.66666667%; } .col-xs-offset-10 { margin-left: 83.33333333%; } .col-xs-offset-9 { margin-left: 75%; } .col-xs-offset-8 { margin-left: 66.66666667%; } .col-xs-offset-7 { margin-left: 58.33333333%; } .col-xs-offset-6 { margin-left: 50%; } .col-xs-offset-5 { margin-left: 41.66666667%; } .col-xs-offset-4 { margin-left: 33.33333333%; } .col-xs-offset-3 { margin-left: 25%; } .col-xs-offset-2 { margin-left: 16.66666667%; } .col-xs-offset-1 { margin-left: 8.33333333%; } .col-xs-offset-0 { margin-left: 0; } @media (min-width: 768px) { .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { float: left; } .col-sm-12 { width: 100%; } .col-sm-11 { width: 91.66666667%; } .col-sm-10 { width: 83.33333333%; } .col-sm-9 { width: 75%; } .col-sm-8 { width: 66.66666667%; } .col-sm-7 { width: 58.33333333%; } .col-sm-6 { width: 50%; } .col-sm-5 { width: 41.66666667%; } .col-sm-4 { width: 33.33333333%; } .col-sm-3 { width: 25%; } .col-sm-2 { width: 16.66666667%; } .col-sm-1 { width: 8.33333333%; } .col-sm-pull-12 { right: 100%; } .col-sm-pull-11 { right: 91.66666667%; } .col-sm-pull-10 { right: 83.33333333%; } .col-sm-pull-9 { right: 75%; } .col-sm-pull-8 { right: 66.66666667%; } .col-sm-pull-7 { right: 58.33333333%; } .col-sm-pull-6 { right: 50%; } .col-sm-pull-5 { right: 41.66666667%; } .col-sm-pull-4 { right: 33.33333333%; } .col-sm-pull-3 { right: 25%; } .col-sm-pull-2 { right: 16.66666667%; } .col-sm-pull-1 { right: 8.33333333%; } .col-sm-pull-0 { right: auto; } .col-sm-push-12 { left: 100%; } .col-sm-push-11 { left: 91.66666667%; } .col-sm-push-10 { left: 83.33333333%; } .col-sm-push-9 { left: 75%; } .col-sm-push-8 { left: 66.66666667%; } .col-sm-push-7 { left: 58.33333333%; } .col-sm-push-6 { left: 50%; } .col-sm-push-5 { left: 41.66666667%; } .col-sm-push-4 { left: 33.33333333%; } .col-sm-push-3 { left: 25%; } .col-sm-push-2 { left: 16.66666667%; } .col-sm-push-1 { left: 8.33333333%; } .col-sm-push-0 { left: auto; } .col-sm-offset-12 { margin-left: 100%; } .col-sm-offset-11 { margin-left: 91.66666667%; } .col-sm-offset-10 { margin-left: 83.33333333%; } .col-sm-offset-9 { margin-left: 75%; } .col-sm-offset-8 { margin-left: 66.66666667%; } .col-sm-offset-7 { margin-left: 58.33333333%; } .col-sm-offset-6 { margin-left: 50%; } .col-sm-offset-5 { margin-left: 41.66666667%; } .col-sm-offset-4 { margin-left: 33.33333333%; } .col-sm-offset-3 { margin-left: 25%; } .col-sm-offset-2 { margin-left: 16.66666667%; } .col-sm-offset-1 { margin-left: 8.33333333%; } .col-sm-offset-0 { margin-left: 0; } } @media (min-width: 992px) { .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { float: left; } .col-md-12 { width: 100%; } .col-md-11 { width: 91.66666667%; } .col-md-10 { width: 83.33333333%; } .col-md-9 { width: 75%; } .col-md-8 { width: 66.66666667%; } .col-md-7 { width: 58.33333333%; } .col-md-6 { width: 50%; } .col-md-5 { width: 41.66666667%; } .col-md-4 { width: 33.33333333%; } .col-md-3 { width: 25%; } .col-md-2 { width: 16.66666667%; } .col-md-1 { width: 8.33333333%; } .col-md-pull-12 { right: 100%; } .col-md-pull-11 { right: 91.66666667%; } .col-md-pull-10 { right: 83.33333333%; } .col-md-pull-9 { right: 75%; } .col-md-pull-8 { right: 66.66666667%; } .col-md-pull-7 { right: 58.33333333%; } .col-md-pull-6 { right: 50%; } .col-md-pull-5 { right: 41.66666667%; } .col-md-pull-4 { right: 33.33333333%; } .col-md-pull-3 { right: 25%; } .col-md-pull-2 { right: 16.66666667%; } .col-md-pull-1 { right: 8.33333333%; } .col-md-pull-0 { right: auto; } .col-md-push-12 { left: 100%; } .col-md-push-11 { left: 91.66666667%; } .col-md-push-10 { left: 83.33333333%; } .col-md-push-9 { left: 75%; } .col-md-push-8 { left: 66.66666667%; } .col-md-push-7 { left: 58.33333333%; } .col-md-push-6 { left: 50%; } .col-md-push-5 { left: 41.66666667%; } .col-md-push-4 { left: 33.33333333%; } .col-md-push-3 { left: 25%; } .col-md-push-2 { left: 16.66666667%; } .col-md-push-1 { left: 8.33333333%; } .col-md-push-0 { left: auto; } .col-md-offset-12 { margin-left: 100%; } .col-md-offset-11 { margin-left: 91.66666667%; } .col-md-offset-10 { margin-left: 83.33333333%; } .col-md-offset-9 { margin-left: 75%; } .col-md-offset-8 { margin-left: 66.66666667%; } .col-md-offset-7 { margin-left: 58.33333333%; } .col-md-offset-6 { margin-left: 50%; } .col-md-offset-5 { margin-left: 41.66666667%; } .col-md-offset-4 { margin-left: 33.33333333%; } .col-md-offset-3 { margin-left: 25%; } .col-md-offset-2 { margin-left: 16.66666667%; } .col-md-offset-1 { margin-left: 8.33333333%; } .col-md-offset-0 { margin-left: 0; } } @media (min-width: 1200px) { .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { float: left; } .col-lg-12 { width: 100%; } .col-lg-11 { width: 91.66666667%; } .col-lg-10 { width: 83.33333333%; } .col-lg-9 { width: 75%; } .col-lg-8 { width: 66.66666667%; } .col-lg-7 { width: 58.33333333%; } .col-lg-6 { width: 50%; } .col-lg-5 { width: 41.66666667%; } .col-lg-4 { width: 33.33333333%; } .col-lg-3 { width: 25%; } .col-lg-2 { width: 16.66666667%; } .col-lg-1 { width: 8.33333333%; } .col-lg-pull-12 { right: 100%; } .col-lg-pull-11 { right: 91.66666667%; } .col-lg-pull-10 { right: 83.33333333%; } .col-lg-pull-9 { right: 75%; } .col-lg-pull-8 { right: 66.66666667%; } .col-lg-pull-7 { right: 58.33333333%; } .col-lg-pull-6 { right: 50%; } .col-lg-pull-5 { right: 41.66666667%; } .col-lg-pull-4 { right: 33.33333333%; } .col-lg-pull-3 { right: 25%; } .col-lg-pull-2 { right: 16.66666667%; } .col-lg-pull-1 { right: 8.33333333%; } .col-lg-pull-0 { right: auto; } .col-lg-push-12 { left: 100%; } .col-lg-push-11 { left: 91.66666667%; } .col-lg-push-10 { left: 83.33333333%; } .col-lg-push-9 { left: 75%; } .col-lg-push-8 { left: 66.66666667%; } .col-lg-push-7 { left: 58.33333333%; } .col-lg-push-6 { left: 50%; } .col-lg-push-5 { left: 41.66666667%; } .col-lg-push-4 { left: 33.33333333%; } .col-lg-push-3 { left: 25%; } .col-lg-push-2 { left: 16.66666667%; } .col-lg-push-1 { left: 8.33333333%; } .col-lg-push-0 { left: auto; } .col-lg-offset-12 { margin-left: 100%; } .col-lg-offset-11 { margin-left: 91.66666667%; } .col-lg-offset-10 { margin-left: 83.33333333%; } .col-lg-offset-9 { margin-left: 75%; } .col-lg-offset-8 { margin-left: 66.66666667%; } .col-lg-offset-7 { margin-left: 58.33333333%; } .col-lg-offset-6 { margin-left: 50%; } .col-lg-offset-5 { margin-left: 41.66666667%; } .col-lg-offset-4 { margin-left: 33.33333333%; } .col-lg-offset-3 { margin-left: 25%; } .col-lg-offset-2 { margin-left: 16.66666667%; } .col-lg-offset-1 { margin-left: 8.33333333%; } .col-lg-offset-0 { margin-left: 0; } }
用户评论