アンパサンド(&)とタイプセレクターを使用して親を結合するSass


100

Sassでのネストに問題があります。次のHTMLがあるとします。

<p href="#" class="item">Text</p>
<p href="#" class="item">Text</p>
<a href="#" class="item">Link</a>

スタイルを次のようにネストしようとすると、コンパイルエラーが発生します。

.item {
    color: black;
    a& {
        color:blue;
   }
}

同じ要素の一部である場合、親セレクターの前にタイプセレクターを参照するにはどうすればよいですか?

回答:


156

クマーが指摘するように、これはサス以来可能3.3.0.rc.1 (Maptastic Maple)でした。

@ at-rootディレクティブにより、1つ以上のルールが親セレクターの下にネストされるのではなく、ドキュメントのルートで発行されます。

@at-rootディレクティブ補間#{}を組み合わせて、意図した結果を得ることができます。

SASS

.item {
    color: black;
    @at-root {
        a#{&} {
            color:blue;
        }
    }
}

// Can also be written like this.
.item {
    color: black;
    @at-root a#{&} {
        color:blue;
    }
}

出力CSS

.item {
    color: black;
}
a.item {
    color: blue;
}

3
これがこの質問の解決策になるはずです。
カイハドリン2014

これは私にとってはうまくいきません... .item a.item何らかの理由で出力が出ています。私a#{&}自身も試してみましたが、結果は同じです。
jaminroe 2015

@jaminroeはLibsassを使用していますか?3.3修正される予定です。
ブレイン

1
@jaminroeは内部でlibsass(node-sass)を使用しているように見えます。その場合は、3.3まで待つ必要があります。
ブレイン、

1
私はこれの少し難しいバージョンを解決していますが、似ていますが、複数のクラスがあるため、タグに追加する必要があります-誰か?
フランクノッケ2017年

29

@at-rootあなたがチェーンアップし、最も近いセレクタを延長する場合のみの方法は、問題を解決することはできません。例として:

#id > .element {
    @at-root div#{&} {
        color: blue;
    }
}

コンパイルされます:

div#id > .element {
    color: blue;
}

.element代わりにタグを結合する必要がある場合はどうなります#idか?

これselector-unify()を解決するSassという関数があります。これを使う@at-rootとターゲットを絞ることができ.elementます。

#id > .element {
    @at-root #{selector-unify(&, div)} {
        color: blue;
    }
}

コンパイルされます:

#id > div.element {
    color: blue;
}

1
これは私に意図した結果を与えませんでした。Sass 3.4.11では、これはに出力され#id > .element #id > div.element { color: blue; }ます。別のアプローチは、使用することですselector_replace#id { > .element { @at-root #{selector-replace(&,'.element', 'div.element')} { color: blue;}}}。読みやすくするための要点次に示します。
ブレイン、

@Blaine目立ったバグを見つけました、ありがとう。私は自分の答えを実用的なソリューションで編集しました。
ベンフレミング

1
そうは言ってselector-replaceも、それを行う別の方法ですが、セレクターが何であるかを知る必要があります。このselector-unify方法には、ミックスインで使用されるという利点があります。
ベンフレミング

素晴らしい答え。
Senthe 2017

8

まず、この回答を書いている時点では、selector&を使用するsass構文はありません。そのようなことを行う場合は、セレクターとアンパサンドの間にスペースが必要になります。例えば:

.item {
    .helper & {

    }
}

// compiles to:
.helper .item {

}

アンパサンドを使用するもう1つの方法は、おそらく(誤って)探しているものです。

.item {
    &.helper {

    }
}

// compiles to:
.item.helper {

}

これにより、他のクラス、ID、疑似セレクターなどでセレクターを拡張できます。残念ながら、これは理論的には.itemaのようにコンパイルされ、明らかに機能しません。

CSSの書き方を考え直したいだけかもしれません。使用できる親要素はありますか?

<div class="item">
    <p>text</p>
    <p>text</p>
    <a href="#">a link</a>
</div>

このようにして、次の方法でSASSを簡単に作成できます。

.item {
    p {
        // paragraph styles here
    }
    a {
        // anchor styles here
    }
}

(補足:HTMLを確認してください。一重引用符と二重引用符を混在させ、pタグにhref属性を配置しています。)


@Lübnah同意しますが、マイクロパフォーマンスを向上させるためのベストプラクティスを定義するつもりはありません。私はhrefタグを付けている誰かにp動作するCSSを書いてもらうことを試みています。
2014

&.selectorは悪い習慣であると言うことに対するサポートはまったくありません。1つのOPが投稿していたのとまったく同じように、多くのユースケースがあります。
Mike Mellor 2017年

@MikeMellor OPは書いている.item { a& }と、私の知る限り承知しているとして(そのためのSASSの構文はありません。私は、彼はおそらくあなたがサスでかなり定期的に使用されている説明アンパサンド構文のようなものを探していたが示唆された。しかし、OPの例を踏まえ、.item { &a }あります有効ではないため、にコンパイルされ.itemaます。答えで言ったように、何か足りないものはありますか?
2017年

OPは.item { a& { ... } }、@ Blaineがで指摘するようになりました.item { @at-root a#{&} { ... } }。重要なのは、要素にクラスがある場合は簡単に実行.item { &.class { ... } }できるため、生のhtml要素で同じことを行えないはずです。OPが投稿された時点でそれを行う方法がなかったからといって、機能が実際にそれを実行することを望んでいるのは彼が不正確であったわけではありません。
Mike Mellor、2017年

4

AFAIKクラスとタグのアンパサンドを同時に組み合わせる場合は、次の構文を使用する必要があります。

.c1 {
  @at-root h1#{&},
    h2#{&}
    &.c2, {
    color: #aaa;
  }
}

コンパイルされます

h1.c1,
h2.c1,
.c1.c2 {
  color: #aaa;
}

その他の使用法(前にクラスを使用する、@at-root複数@at-rootのを使用するなど)はエラーになります。

お役に立てれば幸いです


1
私はちょうどこの、あなたが例えばスパンまたはdivの要素のための行動を変化させるようにしたいミックスインのために非常に有用に使用
サンティアゴarizti

すごい-非常にクール:-)だから、#{&}基本的にコンパイラをだましている-またはこれは常に将来的に機能します!?
Simon_Weaver

sassの@Simon_Weaverでは、内部のすべて#{}が評価されます。&現在のセレクタも意味します。したがって#{&}、に評価され.c1ます。
Vahid

しかし、あなたは&だけでは機能しないという意味でそれをだましています;-)
Simon_Weaver

1
参照@Simon_Weaver このリンクをより多くの例について&
ヴァヒド

3

この機能はSassの最新バージョンに搭載されています。 3.3.0.rc.1(Maptastic Maple)

使用する必要がある密接に関連する2つの機能は、&ネスト可能なスタイル内で補間して親要素を参照できるscriptable と@at-root、直後に続くセレクターまたはCSSのブロックをルートに配置するディレクティブです(出力されたCSSに親があります)

詳細については、このGithubの問題を参照してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.