简体   繁体   English

用于在Twitter中生成列类的LESS循环-它们如何工作?

[英]LESS loops used to generate column classes in twitter - How do they work?

Bootstrap uses some LESS mixins to generate it's column classes (and several other classes); Bootstrap使用一些LESS mixin生成它的类(以及其他几个类);

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

I can see that LESS mixin guards are being used to create loops, and I can understand the code examples that are given in the LESS documentation ; 我可以看到LESS mixin防护用于创建循环,并且我可以理解LESS文档中给出的代码示例;

.loop(@counter) when (@counter > 0) {
  .loop((@counter - 1));    // next iteration
  width: (10px * @counter); // code for each iteration
}

div {
  .loop(5); // launch the loop
}

But I can't seem to grok exactly how the more complex nested guard expressions that bootstrap uses are working. 但是我似乎无法完全理解引导程序使用的更复杂的嵌套保护表达式如何工作。 Could somebody comment the above bootstrap code in a bit more detail to give me an indication of what is going on? 有人可以更详细地评论上面的引导程序代码,以指示我发生了什么吗?

The purpose of the .make-grid-columns() mixin is to generate a long list of selectors which all share the same properties. .make-grid-columns() mixin的目的是生成一长列的选择器,这些选择器均具有相同的属性。 This list can not be hard code in the code because of the number of columns ( @grid-columns ) may vary. 由于列数( @grid-columns )可能有所不同,因此该列表不能是代码中的硬代码。

You already illustrated the basics of a loop in Less in the question yourself. 您已经在问题中的Less中演示了循环的基础。

To understand the mixins you will have to understand Less allows you the use the same mixin name many times. 要了解mixin,您必须了解Less允许您多次使用相同的mixin名称。 Every 'matching' mixins will be compiled into the CSS code. 每个“匹配”的mixins将被编译为CSS代码。 Mixin guards when () enable you to set a condition for the match. when ()使您能够为比赛设置条件when () Mixin保护卫兵。 When the guard not match the mixin is not compiled. 当防护不匹配时,将不编译mixin。 Beside mixins guards you can also use pattern matching, than you can match on value as follows: 除了mixins防护之外,您还可以使用模式匹配,然后可以按如下所示对值进行匹配:

.mixin1(a,@width){}
.mixin1(b,@width){}

The .mixin(a,20px); .mixin(a,20px); call match only the first mixin. 通话只匹配第一个mixin。 Partern matching based on arity (the number of arguments) will also works. 基于稀疏度(参数数量)的部分匹配也将起作用。 Notice that .col(@index) when (@index = 1) does not need a guard ( see also ). 请注意, .col(@index) when (@index = 1)不需要保护( 另请参见 )。 the .col(@index) call has only one argument, so the .col(1); .col(@index)调用只有一个参数,因此.col(1); only matches that mixin based on arity matching. 仅根据Arity匹配来匹配该mixin。 The .col(@index) mixin calls the .col(@index, @list) mixin(s). .col(@index)混合调用.col(@index, @list)混合。 The .col(@index) when (@index = 1) mixin will be only called for the first iteration. .col(@index) when (@index = 1) mixin .col(@index) when (@index = 1).col(@index) when (@index = 1)仅在第一次迭代时调用。 The reason for having two mixins in stead of one is that Less don't support if / else. 拥有两个mixins而不是一个的原因是Less不支持if / else。 The list of selectors can not start or end with a comma and so the first or last item in the list of selectors should differ from the others. 选择器列表不能以逗号开头或结尾,因此选择器列表中的第一项或最后一项应与其他项不同。

Alternatively you can use a mixin with an additional argument: 或者,您可以将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);

The @seperator will be empty ( ~"" ) for the first call and a comma ( "," ) for all other calls. 对于第一个调用,@ seperator将为空( ~"" ),对于所有其他调用","将为逗号( "," )。 Notice that a mixin with default parameters also match calls which not having set values for the defaults: So .call(1); 注意,具有默认参数的混合也匹配没有默认值设置的调用:So .call(1); matches the .call(@a; @b:4; @c:5){} mixin. .call(@a; @b:4; @c:5){}匹配。

As already mentioned in the comments ~"@{list}, @{item}" generates the selector list via string concatenation. 如注释~"@{list}, @{item}"所述,它通过字符串串联生成选择器列表。

The last iteration of .col(@index, @list) when (@index =< @grid-columns) calls col((@grid-columns + 1)....) mixin when @index=@grid-columns and so matches the last .col(@index, @list) when (@index > @grid-columns) mixin in the structure. .col(@index, @list) when (@index =< @grid-columns)调用col((@grid-columns + 1)....) mixin时.col(@index, @list) when (@index =< @grid-columns)的最后一次迭代@index=@grid-columns和因此在结构中.col(@index, @list) when (@index > @grid-columns) mixin .col(@index, @list) when (@index > @grid-columns)匹配最后一个.col(@index, @list) when (@index > @grid-columns)

@{list} { } use selector interpolation to set the list of selectors and his properties. @{list} { }使用选择器插值设置选择器列表及其属性。

Of course you should also read the excellent blog post of @seven-phases-max about this structure to generate a list of selectors. 当然,您还应该阅读有关该结构的@ seven-phases-max 优秀博客文章 ,以生成选择器列表。

Finally you should know that Bootstrap needs such a long list of selectors because of it avoid (partial) attribute selectors. 最后,您应该知道Bootstrap需要这么长的选择器列表,因为它避免了(部分)属性选择器。 In stead of the selector list you can also use the following CSS / Less code: 除了选择器列表,您还可以使用以下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);
}

The reason to avoid attribute selectors is that some browsers compute them slow. 避免使用属性选择器的原因是某些浏览器计算速度较慢。 As can be seen at http://benfrain.com/css-performance-revisited-selectors-bloat-expensive-styles/ , you can discuse this argument. http://benfrain.com/css-performance-revisited-selectors-bloat-expensive-styles/所示 ,您可以忽略此参数。 Personally i think that unused code is a more important performance issue than the use of attribute selectors in most Bootstrap projects. 我个人认为,与大多数Bootstrap项目中使用属性选择器相比,未使用的代码是更重要的性能问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM