Css Less Mixin 不输出所有媒体查询代码

Css Less Mixin not outputting all media query code

我有一个 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;
  }

呼叫class

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

行为解释:

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

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

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


行为验证:

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

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

可能的解决方案:

选项 1: 避免父 .make-margin(@scale) 完全嵌套,因为不需要。您可以直接将其子混入暴露给 .fluid-margin 混入。可在 here.

中找到此方法的示例
.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 定义,只需使用 &(父级选择器)作为如下所示的守卫。这里的 & 指的是调用 mixin 的选择器。由于在 & 下指定的属性将成为选择器块的一部分,并且因为它没有附加括号,所以它仍会产生输出。可以找到此方法的示例 here.

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

第二个选项更简洁(正如您在评论中提到的)。