使用Sass在媒体查询中扩展选择器


86

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

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

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

乍一想,这就是我试图做的事情:

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

但这会产生以下错误:

您不能从@media内部扩展外部选择器。您只能在同一指令中使用@extend选择器。

我如何使用SASS来完成此任务而不必诉诸复制/粘贴样式?


Fyi,这是一个使您正确给出示例的问题:github.com/sass/sass/issues/1050
Ajedi32

Answers:


112

简单的答案是:您不能这样做,因为Sass不能(或不会)为其构成选择器。您不能在媒体查询内部,也不能扩展媒体查询外部的内容。如果只复制它的一个副本而不是尝试组成选择器,那肯定会很好。但是,事实并非如此。

使用混入

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

@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解除此限制(或自己修补)

关于此问题有许多正在进行的讨论(除非您添加了有意义的内容,否则请不要对这些线程作出贡献:维护人员已经意识到用户希望使用此功能,这只是如何实现它以及如何使用该功能的问题。语法应该是)。


@mindeavor这对你有用吗?您可以在媒体查询中使用扩展类吗?在Sass 3.2中?
Yahreen 2014年

1
%foo是不必要的,.foo可以直接使用@include foo
phil294

就我而言,我只是将%placeholder与扩展外部媒体查询一起使用。然后,在媒体查询中,为我的选择器添加了扩展%placeholder。将查看讨论是否附带方便。感谢Cimmanon。
keypaul

11

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

// 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;
  }
}

2

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

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


欢迎使用指向解决方案的链接,但是请确保没有该链接的情况下您的回答是有用的:在该链接周围添加上下文,以便您的其他用户可以了解它的含义和含义,然后引用您所使用页面中最相关的部分如果目标页面不可用,请重新链接。只是链接的答案可能会被删除。
dippas

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);
   }
}

最终,它可能并不比仅使用混入更好,后者是目前公认的答案。


0

我使用断点,但思路相同:

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

如何使用它:

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

有关于mixin的文字,您可以在其中找到有关此选项的更多信息。


-2

你能重组吗?

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

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

如果我正确理解文档,那应该可以。我认为您尝试的方式行不通的原因是,在解析@extend时,它没有看到.item.compact,但这是一个不明智的猜测,因此,用大量的盐来承担吧!:)


您如何编译您的SASS?在外部,使用JS还是某种服务器端组件?
Jason M. Batchelor

正在rails-sass使用SASS v3.2.4通过标准gem进行编译
soundly_typed 2013年

1
似乎已不建议在@media查询内部进行扩展,并且由于在3.3中已被砍掉chriseppstein.github.com/blog/2012/08/23/sass-3-2-is-released(请阅读以下内容: “ @extendCSS指令中的限制”)
Jason M. Batchelor

如果我正确理解了该信息,则可能是导致问题的原因。我想知道您发现了什么!
Jason M. Batchelor
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.