【问题标题】:LESS loops used to generate column classes in twitter - How do they work?用于在 twitter 中生成列类的 LESS 循环 - 它们是如何工作的?
【发布时间】:2014-10-08 00:13:57
【问题描述】:

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 使用的更复杂的嵌套保护表达式是如何工作的。有人可以更详细地评论上面的引导代码,让我知道发生了什么吗?

【问题讨论】:

  • 这个循环与the documentation 中的第二个示例基本相同(涉及递归和守卫)。唯一的区别是附加的“终端”混合,它用于实际呈现由先前迭代生成的选择器列表字符串。那么,对您来说,有哪些确切的陈述有问题呢? (考虑到唯一使用的保护表达式是简单的=&lt;=&gt;)。
  • 抱歉,我是 LESS 的新手,刚刚开始浏览文档(我看到你已经做出了贡献)。我刚刚经历了模式匹配部分 - 这是嵌套的 .col 选择器(例如 .col((@index + 1), @item); )让我感到困惑,但我现在似乎已经明白了。
  • 第二个例子也很棒——干杯。
  • 以防万一,请不要将此 Bootstrap 网格代码视为学习“现代”少的东西。事实上,这段代码(特别是它的“通过字符串连接生成选择器列表”)是非常古老的 sn-p 并且它确实显示了“过时”的做事方式:)。 (奇怪的是,有一次我们有一个很好的 discussion 关于它)。
  • Done.

标签: css twitter-bootstrap loops less


【解决方案1】:

.make-grid-columns() mixin 的目的是生成一长串选择器,它们都共享相同的属性。 此列表不能在代码中硬编码,因为列数(@grid-columns)可能会有所不同。

您已经在问题中自己说明了循环的基础知识。

要了解 mixin,您必须了解 Less 允许您多次使用相同的 mixin 名称。 每个“匹配”的 mixin 都会被编译成 CSS 代码。 Mixin 守卫when () 使您能够设置匹配条件。当守卫不匹配时,mixin 不会被编译。 除了 mixins 守卫之外,您还可以使用模式匹配,而不是您可以按如下方式匹配值:

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

.mixin(a,20px); 调用只匹配第一个 mixin。基于 arity(参数数量)的部分匹配将 也有效。请注意,.col(@index) when (@index = 1) 不需要保护 (see also)。 .col(@index) 调用只有一个参数,因此 .col(1); 仅根据元数匹配匹配该 mixin。 .col(@index) mixin 调用 .col(@index, @list) mixin(s)。 .col(@index) when (@index = 1) mixin 只会在第一次迭代时被调用。有两个 mixin 而不是一个的原因是 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);

第一次调用的@分隔符为空 (~""),所有其他调用的逗号 (",")。 请注意,具有默认参数的 mixin 也会匹配没有设置默认值的调用: 所以.call(1); 匹配.call(@a; @b:4; @c:5){} mixin。

正如 cmets ~"@{list}, @{item}" 中已经提到的那样,通过字符串连接生成选择器列表。

.col(@index, @list) when (@index =&lt; @grid-columns) 的最后一次迭代调用 col((@grid-columns + 1)....) mixin 当 @index=@grid-columns 匹配结构中的最后一个 .col(@index, @list) when (@index &gt; @grid-columns) mixin。

@{list} { }使用选择器插值来设置选择器列表及其属性。

当然,您还应该阅读@seven-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 项目中,未使用的代码是比使用属性选择器更重要的性能问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 2012-05-17
    • 2021-07-29
    • 2019-02-13
    • 2014-12-11
    相关资源
    最近更新 更多