Bootstrap使用一些LESS mixins来生成它的column类(以及其他几个类);
.make-grid-columns() {
// Common styles for all sizes of grid columns, widths 1-12
.col(@index) when (@index = 1) { // initial
@item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
.col((@index + 1), @item);
}
.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}");
}
.col(@index, @list) when (@index > @grid-columns) { // terminal
@{list} {
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
}
我可以看到LESS mixin guards被用来创建循环,我可以理解LESS documentation中给出的代码示例;
.loop(@counter) when (@counter > 0) {
.loop((@counter - 1)); // next iteration
width: (10px * @counter); // code for each iteration
}
div {
.loop(5); // launch the loop
}
但我似乎无法确切地知道bootstrap使用的更复杂的嵌套保护表达式是如何工作的。有人可以更详细地评论上面的引导代码,以便告诉我发生了什么事吗?
答案 0 :(得分:1)
.make-grid-columns()
mixin的目的是生成一长串选择器,它们共享相同的属性。
此列表不能是代码中的硬代码,因为列数(@grid-columns
)可能会有所不同。
您已经在问题中用Less来说明循环的基础知识。
要了解mixins,您必须了解Less允许您多次使用相同的mixin名称。
每个匹配的&#39; mixins将被编译成CSS代码。
Mixin guards when ()
使您能够为匹配设置条件。当守卫不匹配时,mixin不会被编译。
除了mixins防护之外,您还可以使用模式匹配,而不是按照以下方式匹配值:
.mixin1(a,@width){}
.mixin1(b,@width){}
.mixin(a,20px);
来电仅匹配第一个混音。基于arity(参数个数)的Partern匹配将
也有效。请注意,.col(@index) when (@index = 1)
不需要警卫(see also)。
.col(@index)
调用只有一个参数,因此.col(1);
仅匹配基于arity匹配的mixin。
.col(@index)
mixin调用.col(@index, @list)
mixin(s)。 .col(@index) when (@index = 1)
mixin仅在第一次迭代时被调用。有两个mixin而不是一个mix的原因是Less不支持if / else。选择器列表不能以逗号开头或结尾,因此选择器列表中的第一个或最后一个项应该与其他项不同。
或者你可以使用带有附加参数的mixin:
.mixin(@iterator; @item:~""; @seperator:~"") when (@iterator < 5){
@list: ~"@{item} @{seperator} @{iterator}";
.mixin((@iterator + 1); @list; ",");
}
.mixin(@iterator; @list; @seperator) when (@iterator = 5){
.selector{
@{list}: value;
}
}
.mixin(1);
@seperator对于第一次调用将为空(~""
),对于所有其他调用将为逗号(","
)。
请注意,具有默认参数的mixin也匹配没有默认设置值的调用:
因此.call(1);
与.call(@a; @b:4; @c:5){}
mixin相匹配。
正如评论中已经提到的那样~"@{list}, @{item}"
通过字符串连接生成选择器列表。
当.col(@index, @list) when (@index =< @grid-columns)
时,col((@grid-columns + 1)....)
调用@index=@grid-columns
的最后一次调用mixin与结构中的最后一个.col(@index, @list) when (@index > @grid-columns)
mixin匹配。
@{list} { }
使用选择器插值来设置选择器列表及其属性。
当然,您还应该阅读关于此结构的@ 7-phases-max的excellent blog post以生成选择器列表。
最后你应该知道Bootstrap需要这么长的选择器列表,因为它避免了(部分)属性选择器。您可以使用以下CSS / Less代码代替选择器列表:
[class^="col-"], [class*=" col-"]
{
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);
}
避免使用属性选择器的原因是某些浏览器计算速度很慢。从http://benfrain.com/css-performance-revisited-selectors-bloat-expensive-styles/可以看出,你可以讨论这个论点。我个人认为,在大多数Bootstrap项目中,未使用的代码比使用属性选择器更重要。