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

Posted

技术标签:

【中文标题】使用 Sass 从媒体查询中扩展选择器【英文标题】:Extending selectors from within media queries with Sass 【发布时间】:2013-01-28 06:04:50 【问题描述】:

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

.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 来完成此操作,而不必求助于复制/粘贴样式?

【问题讨论】:

仅供参考,这里有一个问题可以使您提供的示例正常工作:github.com/sass/sass/issues/1050 【参考方案1】:

简单的答案是:你不能,因为 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 解除此限制(或自行修补)

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

https://github.com/sass/sass/issues/1050 https://github.com/sass/sass/issues/456

【讨论】:

@mindeavor 这对你有用吗?您能够在媒体查询中使用扩展类吗?在 Sass 3.2 中? %foo不需要,.foo可以直接@include foo 就我而言,我刚刚使用 %placeholder 来扩展外部媒体查询。然后,在媒体查询中,为我的选择器添加了extend %placeholder。看看讨论是否有方便的东西。谢谢西马农。【参考方案2】:

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

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

【讨论】:

【参考方案3】:

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

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

【讨论】:

欢迎提供解决方案链接,但请确保您的答案在没有它的情况下有用:add context around the link 这样您的其他用户就会知道它是什么以及为什么会出现,然后引用最相关的您链接到的页面的一部分,以防目标页面不可用。 Answers that are little more than a link may be deleted.【参考方案4】:

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

Cross-Media Query @extend Directives in Sass

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

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


.a 
    @include _(clear);

.b 
    @include _(clear);

.c 
    @include breakpoint(medium) 
      @include _(clear);
   

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

【讨论】:

【参考方案5】:

我用断点,但思路是一样的:

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

使用方法:

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

a texta text 是关于 mixins 的,您可以在其中找到有关此选项的更多信息。

【讨论】:

【参考方案6】:

你能重组吗?

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

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

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

【讨论】:

你是如何编译你的 SASS 的?在外部,使用 JS,还是使用某种服务器端组件? 它正在通过标准rails-sass gem 编译,使用 SASS v3.2.4 看起来在@media 查询中扩展的能力已被弃用,并且由于在 3.3 中被取消:chriseppstein.github.com/blog/2012/08/23/sass-3-2-is-released(阅读“CSS 指令中@extend 的限制”的区域) 如果我正确理解了该信息,那可能就是导致问题的原因。我很想知道你发现了什么!

以上是关于使用 Sass 从媒体查询中扩展选择器的主要内容,如果未能解决你的问题,请参考以下文章

我必须使用啥 webpack 加载器来组合媒体查询?

如何使用媒体查询或运算符使 SASS 嵌套嵌套媒体查询工作

如何添加“定向媒体查询”来引导4 sass媒体查询

如何在 CSS 3 媒体查询中使用 SASS 逻辑 [重复]

在 CSS3 媒体查询中使用 Sass 变量

在选择器中定义 CSS 媒体查询