103

我有一个项目类和一个紧凑的“修饰符”类:

.item { ... }
.item.compact { /* styles to make .item smaller */ }

这可以。但是,我想添加一个查询,当屏幕足够小时@media强制类紧凑。.item

乍一看,这就是我试图做的:

.item { ... }
.item.compact { ... }
@media (max-width: 600px) {
  .item { @extend .item.compact; }
}

但这会产生以下错误:

您不能在@media 中@extend 外部选择器。您只能在同一指令中 @extend 选择器。

我将如何使用 SASS 完成此操作,而不必求助于复制/粘贴样式?

4

6 回答 6

137

简单的答案是:你不能,因为 Sass 不能(或不会)为它编写选择器。您不能在媒体查询内部并扩展媒体查询之外的内容。如果它只是简单地复制它而不是尝试编写选择器,那肯定会很好。但事实并非如此,所以你不能。

使用混合

如果您要在媒体查询内部和外部重用一段代码并且仍然希望它能够扩展它,那么编写一个 mixin 和一个扩展类:

@mixin foo {
    // do stuff
}

%foo {
    @include foo;
}

// usage
.foo {
    @extend %foo;
}

@media (min-width: 30em) {
    .bar {
        @include foo;
    }
}

从外部扩展媒体查询中的选择器

这不会真正帮助您的用例,但它是另一种选择:

%foo {
  @media (min-width: 20em) {
    color: red;
  }
}

@media (min-width: 30em) {
  %bar {
    background: yellow;
  }
}

// usage
.foo {
  @extend %foo;
}

.bar {
  @extend %bar;
}

等到 Sass 解除这个限制(或者自己修补)

关于这个问题有许多正在进行的讨论(请不要对这些线程做出贡献,除非你有一些有意义的东西要添加:维护者已经意识到用户需要这个功能,这只是一个如何实现它以及它是什么的问题语法应该是)。

于 2013-02-12T20:46:13.993 回答
13

作为记录,这是我最终解决问题的方法,只复制了一次生成的样式:

// This is where the actual compact styles live
@mixin compact-mixin { /* ... */ }

// Include the compact mixin for items that are always compact
.item.compact { @include compact-mixin; }

// Here's the tricky part, due to how SASS handles extending
.item { ... }
// The following needs to be declared AFTER .item, else it'll
// be overridden by .item's NORMAL styles.
@media (max-width: 600px) {
  %compact { @include compact-mixin; }

  // Afterwards we can extend and
  // customize different item compact styles
  .item {
    @extend %compact;
    /* Other styles that override %compact */
  }
  // As shown below, we can extend the compact styles as many
  // times as we want without needing to re-extend
  // the compact mixin, thus avoiding generating duplicate css
  .item-alt {
    @extend %compact;
  }
}
于 2013-02-12T21:58:48.927 回答
2

我相信 SASS/SCSS 不支持@extend媒体查询中的指令。http://designshack.net/articles/css/sass-and-media-queries-what-you-can-and-cant-do/

您可能需要改用 mixin,尽管需要根据您的目标权衡代码膨胀。

于 2013-02-12T20:48:42.647 回答
1

这是我找到的最干净的部分解决方案。它在可能的情况下利用 @extend 并在媒体查询中回退到 mixins。

Sass 中的跨媒体查询 @extend 指令

有关详细信息,请参阅文章,但要点是您调用 mixin 的“占位符”,然后决定是输出 @extend 还是 @include。

@include placeholder('clear') {
   clear: both;
   overflow: hidden;
}

.a {
    @include _(clear);
}
.b {
    @include _(clear);
}
.c {
    @include breakpoint(medium) {
      @include _(clear);
   }
}

最终,它可能并不比仅使用 mixins 更好,这是目前公认的答案。

于 2014-07-01T18:16:39.610 回答
0

我使用断点,但这是相同的想法:

@mixin bp-small {
    @media only screen and (max-width: 30em) {
        @content;
    }

如何使用它:

.sidebar {
    width: 60%;
    float: left;
    @include bp-small {
        width: 100%;
        float: none;
    }
}

一个关于 mixins 的文本,您可以在其中找到有关此选项的更多信息。

于 2018-03-23T14:42:32.877 回答
-2

可以重组吗?

.compact { //compact-styles }
.item {}
.item.compact { @extend .compact } 

@media (max-width: 600px) {
    .item { @extend .compact; }
}

如果我正确理解了文档,那应该可以。我认为您尝试的方式行不通的原因是它在解析@extend 时看不到 .item.compact,但这是一个不知情的猜测,所以请用一卡车的盐来处理!:)

于 2013-02-12T20:18:46.527 回答