web-dev-qa-db-ja.com

Sassを使用したメディアクエリ内からのセレクターの拡張

アイテムクラスとコンパクトな「修飾子」クラスがあります。

.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を使用してこれをどのように達成できますか?

67
mindeavor

簡単な答えは、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がこの制限を解除するまで待ちます(または自分でパッチを適用します)

この問題に関しては、現在進行中の議論が数多くあります(追加する意味のあるものがない限り、これらのスレッドに貢献しないでください。メンテナーは、ユーザーがこの機能を望んでいることを既に認識しています。構文は次のとおりです)。

80
cimmanon

記録のために、生成されたスタイルを1回だけ複製することで問題を解決した方法を次に示します。

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

SASS/SCSSは@extendクエリ内のディレクティブ。 http://designshack.net/articles/css/sass-and-media-queries-what-you-can-and-cant-do/

代わりにmixinを使用する必要があるかもしれませんが、コードの肥大化は目的に対して比較検討する必要があります。

2
JHogue

これは私が見つけた最もクリーンで部分的な解決策です。可能な場合は@extendを利用し、メディアクエリ内ではmixinにフォールバックします。

Sassのクロスメディアクエリ@extendディレクティブ

詳細については記事を参照してください。ただし、要点は、@ extendまたは@includeを出力するかどうかを決定するmixin「プレースホルダー」を呼び出すことです。

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

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

最終的には、現在受け入れられている答えであるミックスインを使用するよりも良いとは限りません。

1
Tom Genoni

私はブレークポイントを使用しますが、それは同じ考えです:

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

それの使い方:

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

テキスト があり、このオプションの詳細を確認することができます。

0
Nesha Zoric