【问题标题】:Css Less Mixin not outputting all media query codeCss Less Mixin 不输出所有媒体查询代码
【发布时间】:2023-03-26 15:33:01
【问题描述】:

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

【问题讨论】:

  • 这个很有趣。我有一个解决方案,但没有当前解决方案不起作用的原因。当我有理由时会发布答案。 This pen 有解决办法(点击 CSS 标签中的眼睛图标查看编译后的输出)。
  • 啊,我又犯了一个小学生错误,但结果很奇怪。

标签: css less less-mixins


【解决方案1】:

行为说明:

在您的 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() mixin 中添加另一个 .make-margin(@scale) 行。这也将产生默认输出,因为子 mixin 位于同一范围内,因此 mixin 调用能够到达它们。

可能的解决方案:

选项 1: 完全避免父 .make-margin(@scale) 嵌套,因为它不需要。您可以直接将其子 mixin 暴露给 .fluid-margin mixin。可以在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;
    }
}

第二个选项更简洁(正如您在 cmets 中提到的那样)。

【讨论】:

  • 我认为选项 2 是更简洁的选项 - 再次感谢您的帮助,Harry。
  • 说到解释。是的,这正是发生的事情。
  • 说到选项:3rd one 为神秘的谜题爱好者(前提是变量和属性使用相同的标识符...)。
  • @seven-phases-max - 很棒的技术!
猜你喜欢
  • 2012-08-27
  • 2011-12-08
  • 2013-04-18
  • 2023-03-08
  • 1970-01-01
  • 2012-06-09
  • 2020-03-04
  • 1970-01-01
  • 2013-05-04
相关资源
最近更新 更多