1

我有一个 mixin——它比我以前做过的任何事情都要复杂一点,所以现在我遇到了一个我无法深入了解的问题。问题是永远不会创建默认值。我还明确添加了移动优先媒体查询,但这也不起作用。

.fluid-margin(@top; @right; @bottom; @left;)
{
    .make-margin(@xs-gutter-width);

    @media @sm-screen {
        .make-margin(@sm-gutter-width);
    }
    @media @md-screen {
        .make-margin(@md-gutter-width);
    }
    @media @lg-screen {
        .make-margin(@lg-gutter-width);
    }

    .make-margin(@scale)
    {
        .make-margin(@scale) when (@top > 0)
        {
            margin-top:@scale * @top;
        }
        .make-margin(@scale) when (@right > 0)
        {
            margin-right:@scale * @right;
        }
        .make-margin(@scale) when (@bottom > 0)
        {
            margin-bottom:@scale * @bottom;
        }
        .make-margin(@scale) when (@left > 0)
        {
            margin-left:@scale * @left;
        }
    }
}

输出

.list-section-header {
  overflow: hidden;
  text-align: center;
}
@media only screen and (min-width:600px) and (max-width:899px) {
  .list-section-header {
    margin-top: 2.25rem;
    margin-bottom: 2.25rem;
  }
}
@media only screen and (min-width:900px) and (max-width:1199px) {
  .list-section-header {
    margin-top: 2.25rem;
    margin-bottom: 2.25rem;
  }
}
@media only screen and (min-width:1200px) and (max-width:1280px) {
  .list-section-header {
    margin-top: 3rem;
    margin-bottom: 3rem;
  }

调用类

.fluid-margin(1.5rem; 0; 1.5rem; 0);
4

1 回答 1

3

行为说明:

在您的 mixin 代码中,有一个外部(父).make-margin(@scale)mixin,其中只有一些受保护的 mixin。通常,当调用 mixin 时,只会输出其中存在的属性或属于任何选择器块的属性。当第一次调用 mixin 时,这里没有任何输出,因为父 mixin 的内容只是前面所述的附加 mixin。

当第一次调用 mixin 时(调用默认设置),它会将.make-margin()父 mixin 的所有内容限定在.fluid-margin()mixin 中,从而公开其所有子 mixin。由于这种暴露,当您从其他媒体查询中第二次(和后续)调用它时,编译器能够处理它们并产生所需的输出。

基本上,第一个 mixin 调用(默认)除了将其内容暴露给调用者作用域外,什么都不做。


行为验证:

可以通过执行以下任何一项来验证上述声明。

  1. 注释掉第一个 mixin 调用(输出默认设置的那个),你会注意到即使是其他媒体查询也不会产生任何输出。这是因为受保护的子mixin.fluid-margin().
  2. 在第一个下面直接重复默认的 mixin 调用 ( .make-margin(@xs-gutter-width);),您会注意到它确实会产生默认输出,因为子 mixin 现在暴露于.fluid-margin().
  3. .make-margin(@scale)在父.make-margin()mixin 中添加另一行。这也将产生默认输出,因为子 mixin 在同一范围内,因此 mixin 调用能够到达它们。

可能的解决方案:

选项 1:完全避免父.make-margin(@scale)嵌套,因为它不需要。您可以直接将其子 mixin 暴露给.fluid-marginmixin。可以在此处找到此方法的示例。

.make-margin(@scale) when (@top > 0){
    margin-top: @scale * @top;
}
.make-margin(@scale) when (@right > 0){
    margin-right: @scale * @right;
}
.make-margin(@scale) when (@bottom > 0){
    margin-bottom: @scale * @bottom;
}
.make-margin(@scale) when (@left > 0){
    margin-left: @scale * @left;
}

选项 2:不要在父级中使用另一个 mixin 定义,只需将&(parent selector) 用于下面的守卫。这里的&将指的是从其中调用 mixin 的选择器。由于在下面指定的属性&将成为选择器块的一部分,并且因为它没有附加括号,所以它仍然会产生输出。可以在此处找到此方法的示例。

.make-margin(@scale)
{
    & when (@top > 0){
        margin-top: @scale * @top;
    }
    & when (@right > 0){
        margin-right: @scale * @right;
    }
    & when (@bottom > 0){
        margin-bottom: @scale * @bottom;
    }
    & when (@left > 0){
        margin-left: @scale * @left;
    }
}

第二个选项更干净(正如您在评论中提到的那样)。

于 2015-02-16T17:11:56.577 回答