SASS嵌套mixins问题

时间:2017-05-29 19:03:08

标签: sass

我目前正在努力解决以下问题(请注意:实际的mixins有点复杂,我已经简化了它们,但我肯定希望使用mixins来实现这种方法)

我有一个断点的混音:

=

我有这个mixin将边距应用于元素(实际的mixin有点复杂)

@mixin sm {
    @media (max-width: 740px) {
        @content;
    }
}
@mixin lg {
    @media (min-width: 741px) {
        @content;
    }
}

所以基本上,我在一个元素上使用mixin,并且基于视口大小,元素获得不同的边距。问题是这样的:如果我想使用margin mixin作为元素,但只在大视口大小上使用,我会得到这样的结果:

@mixin margin {
    @include sm {
        margin: 10px;
    }
    @include lg {
        margin: 20px;
    }
}

输出现在变为:

.foo {
    @include lg {
        @include margin;
    }
}

哪个有道理,但我希望有这样的输出:

@media (min-width: 741px) and (max-width: 740px) {
  .foo {
      margin: 10px; 
    } 
}   
@media (min-width: 741px) and (min-width: 741px) {
  .foo {
        margin: 20px; 
    } 
}

理想情况下,我不会在margin mixin中包含断点mixin,但我想不出任何其他方法。有谁知道这是否可行?

谢谢!

1 个答案:

答案 0 :(得分:1)

我能想到的一种易于使用的方法是,您可以通过条件和可选参数扩展边距,以便在必要时排除特定的媒体查询。

@mixin margin($sm: true, $lg: true) {
    @if $sm {
      @include sm {
          margin: 10px;
      }
    }
    @if $lg {
      @include lg {
          margin: 20px;
      }
    }
}

.margin {
  @include margin;
}

.margin-only-on-lg {
  @include margin(false, true);
}

使用mixin仍然很简单,只有mixin本身才需要使用媒体查询。它也非常强大,因此如果开发人员不知道可选参数,他可以在不破坏逻辑的情况下执行以下操作。

.foo {
    @include lg {
        @include margin;
    }
}

但当然它会输出一些不必要的CSS。如果你在这里看到一个问题和/或你想要一个更灵活的方法来传递不同的具体边缘值作为参数,那么在编译时结合warnings for missing optional parameters进行以下修改(参见我的答案)可能是更好的方法:

@mixin margin($sm: false, $lg: false) {
    @include sm {
      margin: warn-on-false("margin()", $sm, 10px);
    }
    @include lg {
      margin: warn-on-false("margin()", $sm, 20px);;
    }
}

.margin {
  @include margin(null, null); // I'm aware of the parameters, but use the default values
}

.margin-only-on-lg {
  @include margin(0, null); // set margin to 0 on small screen size; use default for lg 
}

这样,由于缺乏可选参数而导致定义.foo类的上述(不期望的)方式在编译时导致警告,此外开发人员可以在特殊情况下使用不同的边缘值。当然,也可以简单地使用布尔参数并使它们成为必需参数。