@for 和 @each 在 Sass 中生成网格列 类

@for and @each to generate grid column classes in Sass

我正在尝试找到在 Sass 中为我正在处理的网站创建动态列 类 的方法。这就是我目前所拥有的:

$breakpoints: (small: 0, medium: 640px, large: 1024px);
$grid-columns: 12;

@for $i from 1 through $grid-columns {
  @each $key, $value in $breakpoints {
    .#{$key}-#{$i} { width: (100% / $grid-columns) * $i }
  }
}

这是我编译后得到的:

.small-1 { width: 8.33333%; }

.medium-1 { width: 8.33333%; }

.large-1 { width: 8.33333%; }

.small-2 { width: 16.66667%; }

.medium-2 { width: 16.66667%; }

.large-2 { width: 16.66667%; }

...

但其实我想得到的是:

.small-1, .medium-1, .large-1 { width: 8.33333%; }

.small-2, .medium-2, .large-2 { width: 16.66667%; }

...

有什么想法吗? :)

好吧,所以我犯了一个错误,没有想太多,因为事实上,我真正需要的是以下输出:

.small-1 { width: 8.33333%; }
.small-2 { width: 16.66667%; }
.small-3 { width: 25%; }
...

@media only screen and (min-width: 640px) {
  /* line 43, ../scss/_grid.scss */
  .medium-1 { width: 8.33333%; }
  .medium-2 { width: 16.66667%; }
  .medium-3 { width: 25%; }
  ...
}
@media only screen and (min-width: 1024px) {
  .large-1 { width: 8.33333%; }
  .large-2 { width: 16.66667%; }
  .large-3 { width: 25%; }
  ...
}

我通过以下代码实现了这一点:

$breakpoints: (small: 0, medium: 640px, large: 1024px);
$grid-columns: 12;

@each $key, $value in $breakpoints {
  @if $value == 0 {
    @for $i from 1 through $grid-columns {
      .#{$key}-#{$i} { width: (100% / $grid-columns) * $i; };
    }
  } @else if $value != 0 {
    @include breakpoint(#{$key}) {;
    @for $i from 1 through $grid-columns {
      .#{$key}-#{$i} { width: (100% / $grid-columns) * $i; };
    };
    };
  }
}

希望这对其他人也有帮助 ;)

编辑:由于@Ram Kumar 对 @include breakpoint(#{$key}) 部分有点好奇,我在下面添加了混合代码。必须有更好或更简单的方法,但这是我能想到的。如果您正在寻找一个简单的解决方案,您只需要以下内容的第一行:

@mixin breakpoint($point) {

    // breakpoint(medium), breakpoint(large)...
    @each $key, $value in $breakpoints {
        @if $point == $key and not ($value == 0) {
            @media only screen and (min-width: #{$value}) { @content; }
        }
    }

    // breakpoint(small only), breakpoint(medium only), breakpoint(large only)...
    $i: 1;
    @each $key, $value in $breakpoints {

        $bp-only: $key only;
        $bp-keys: map-keys($breakpoints);
        $bp-values: map-values($breakpoints);

        @if $point == $bp-only and $value == 0 {
            @media only screen and (max-width: #{nth($bp-values, $i + 1)}) { @content; }
        }
        @if $point == $bp-only and not ($value == 0) and not ($key == nth($bp-keys, -1)) {
            @media only screen and (min-width: #{$value}) and (max-width: #{nth($bp-values, $i)}) { @content; }
        }
        @if $point == $bp-only and $key == nth($bp-keys, -1) {
            @media only screen and (min-width: #{$value}) { @content; }
        }

        $i: $i + 1;
    }

    // breakpoint(medium down), breakpoint(large down)...
    @each $key, $value in $breakpoints {
        $bp-down: $key down;
        @if $point == $bp-down and not ($value == 0) {
            @media only screen and (max-width: #{$value}) { @content; }
        }
    }

}