SASS @each跳过特定行(如果存在变量)

时间:2019-07-10 15:34:02

标签: css sass

我正在尝试使用SASS构建网格系统,到目前为止还不错,但是如果断点是“ xs”,我想跳过@media #{$query} {}行,因为xs不再需要媒体查询。

有人可以建议吗?

$default__gridColumns: 18;
$default__flexColumns: 12;
$default__gutter: 20px;

$default__breakpoints: (
    'xs': 'screen and (max-width: 767px)',
    'sm': 'screen and (min-width:768px) and (max-width:1023px)',
    'md': 'screen and (min-width:1024px) and (max-width:1200px)',
    'lg': 'screen and (min-width:1201px) and (max-width:1440px)'
);

.flex {
    display: flex;
    margin: 0 -$default__gutter;
    padding: 0 $default__gutter;
    > *[class^="span__"] {
        padding: 0 $default__gutter;
        position: relative;
    }
    @each $breakpoint, $query in $default__breakpoints {

        @media #{$query} {

            @for $i from 1 through $default__flexColumns {
                > .span__#{$breakpoint}--#{$i} {
                    width: $i/$default__flexColumns * 100%;
                }
                > .span__#{$breakpoint}--offsetLeft-#{$i} {
                    margin-left: $i/$default__flexColumns * 100%;
                }
                > .span__#{$breakpoint}--offsetRight-#{$i} {
                    margin-right: $i/$default__flexColumns * 100%;
                }
                > .span__#{$breakpoint}--push-#{$i} {
                    left: $i/$default__flexColumns * 100%;
                }
                > .span__#{$breakpoint}--pull-#{$i} {
                    right: $i/$default__flexColumns * 100%;
                }
                > .visible__#{$breakpoint} {
                    display: block !important;
                }
                > .visible__#{$breakpoint}--flex {
                    display: flex !important;
                }
                > .visible__#{$breakpoint}--inline {
                    display: inline !important;
                }
                > .visible__#{$breakpoint}--inlineBlock {
                    display: inline-block !important;
                }
                > .hidden__#{$breakpoint}--inlineBlock {
                    display: none !important;
                }
            }
        }
    }
}

2 个答案:

答案 0 :(得分:1)

已更新为使用@mixin

您可以使用@if指令来测试$breakpoint的值:

$default__gridColumns: 18;
$default__flexColumns: 12;
$default__gutter: 20px;

$default__breakpoints: (
    'xs': 'screen and (max-width: 767px)',
    'sm': 'screen and (min-width:768px) and (max-width:1023px)',
    'md': 'screen and (min-width:1024px) and (max-width:1200px)',
    'lg': 'screen and (min-width:1201px) and (max-width:1440px)'
);

@mixin flex_column( $breakpoint ) {
  @for $i from 1 through $default__flexColumns {
                > .span__#{$breakpoint}--#{$i} {
                    width: $i/$default__flexColumns * 100%;
                }
                > .span__#{$breakpoint}--offsetLeft-#{$i} {
                    margin-left: $i/$default__flexColumns * 100%;
                }
                > .span__#{$breakpoint}--offsetRight-#{$i} {
                    margin-right: $i/$default__flexColumns * 100%;
                }
                > .span__#{$breakpoint}--push-#{$i} {
                    left: $i/$default__flexColumns * 100%;
                }
                > .span__#{$breakpoint}--pull-#{$i} {
                    right: $i/$default__flexColumns * 100%;
                }
                > .visible__#{$breakpoint} {
                    display: block !important;
                }
                > .visible__#{$breakpoint}--flex {
                    display: flex !important;
                }
                > .visible__#{$breakpoint}--inline {
                    display: inline !important;
                }
                > .visible__#{$breakpoint}--inlineBlock {
                    display: inline-block !important;
                }
                > .hidden__#{$breakpoint}--inlineBlock {
                    display: none !important;
                }
            }
}

.flex {
    display: flex;
    margin: 0 -$default__gutter;
    padding: 0 $default__gutter;
    > *[class^="span__"] {
        padding: 0 $default__gutter;
        position: relative;
    }
    @each $breakpoint, $query in $default__breakpoints {

        @if $breakpoint == xs {
          @include flex_column( #{$breakpoint} )
        } @else {

        @media #{$query} {
          @include flex_column( #{$breakpoint} )
        }
    }
    }
}

由于CSS如何使用@media查询变量中的括号进行编译,实际上并没有一种方法可以仅跳过所需的行。

答案 1 :(得分:1)

您可以使用map-remove

$default__breakpoints: (
    'xs': 'screen and (max-width: 767px)',
    'sm': 'screen and (min-width:768px) and (max-width:1023px)',
    'md': 'screen and (min-width:1024px) and (max-width:1200px)',
    'lg': 'screen and (min-width:1201px) and (max-width:1440px)'
);

.flex {
    // ...
    $custom_breakpoints: map-remove($default__breakpoints, 'xs');
    @each $breakpoint, $query in $custom_breakpoints {
        @media #{$query} {
            // code
        }
    }
}

它返回地图的副本,因此您不必担心将其从$default__breakpoints变量中删除。


编辑:我误解了您的问题。您可以使用@at-root来做到这一点,尽管这样做确实会增加一个额外的缩进量:

$default__breakpoints: (
    'xs': 'screen and (max-width: 767px)',
    'sm': 'screen and (min-width:768px) and (max-width:1023px)',
    'md': 'screen and (min-width:1024px) and (max-width:1200px)',
    'lg': 'screen and (min-width:1201px) and (max-width:1440px)'
);

.flex {
  // ...
  @each $breakpoint, $query in $default__breakpoints {
    @media #{$query} {
      @at-root (with: if($breakpoint == 'xs', rule, all)) {
        .selector {
          content: 'value';
        }
      }
    }
  }
}

将编译为

.flex .selector {
  content: "value";
}
@media screen and (min-width:768px) and (max-width:1023px) {
  .flex .selector {
    content: "value";
  }
}
@media screen and (min-width:1024px) and (max-width:1200px) {
  .flex .selector {
    content: "value";
  }
}
@media screen and (min-width:1201px) and (max-width:1440px) {
  .flex .selector {
    content: "value";
  }
}
相关问题