web-dev-qa-db-fra.com

Sass combinant le parent en utilisant esperluette (&) avec des sélecteurs de type

J'ai des problèmes pour nidifier à Sass. Disons que j'ai le code HTML suivant:

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

Lorsque j'essaie d'imbriquer mes styles dans les éléments suivants, une erreur de compilation survient:

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

Comment référencer un sélecteur de type avant le sélecteur parent lorsqu'il fait partie du même élément?

85
McShaman

Comme le souligne Kumar , cela est possible depuis Sass 3.3.0.rc.1 (Maptastic Maple).

La directive @ at-root entraîne l’émission d’une ou de plusieurs règles à la racine du document, plutôt que leur imbrication sous leur sélecteur parent.

Nous pouvons combiner le @at-root directive avec interpolation #{} pour arriver au résultat souhaité.

[~ # ~] sass [~ # ~]

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

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

Sortie CSS

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

La méthode @at-root - only ne résoudra pas le problème si vous souhaitez étendre le sélecteur le plus proche de la chaîne. Par exemple:

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

Compiler pour:

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

Et si vous avez besoin de joindre votre tag à .element Au lieu de #id?

Il existe une fonction dans Sass appelée selector-unify() qui résout ce problème. En utilisant ceci avec @at-root, Il est possible de cibler .element.

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

Compiler pour:

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

Pour commencer, (au moment de l'écriture de cette réponse), il n'y a pas de syntaxe sass qui utilise sélecteur &. Si vous deviez faire quelque chose comme ça, vous auriez besoin d'un espace entre le sélecteur et la perluète. Par exemple:

.item {
    .helper & {

    }
}

// compiles to:
.helper .item {

}

L'autre façon d'utiliser l'esperluette est probablement ce que vous recherchez (à tort):

.item {
    &.helper {

    }
}

// compiles to:
.item.helper {

}

Cela vous permet d’étendre les sélecteurs avec d’autres classes, identifiants, pseudo-sélecteurs, etc. Malheureusement pour votre cas, cela compilerait théoriquement avec quelque chose comme .itema qui ne fonctionne évidemment pas.

Vous voudrez peut-être simplement repenser la façon dont vous écrivez votre CSS. Y a-t-il un élément parent que vous pourriez utiliser?

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

De cette façon, vous pourriez facilement écrire votre SASS de la manière suivante:

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

(Remarque: vous devriez jeter un coup d'œil sur votre code HTML. Vous mélangez des guillemets simples ET des attributs href sur des balises p.)

7
imjared

Si je veux bien combiner esperluette pour la classe et les balises en même temps, vous devez utiliser cette syntaxe:

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

va compiler pour

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

Autres utilisations (comme utiliser la classe avant @at-root ou en utilisant plusieurs @at-roots) entraînera des erreurs.

J'espère que ça va être utile

4
Vahid

Cette fonctionnalité a atterri dans la dernière version de Sass, 3.3.0.rc.1(Maptastic Maple)

Les deux fonctionnalités étroitement liées que vous devez utiliser sont le scriptable &, Que vous pouvez interpoler dans un style imbriqué pour référencer les éléments parents, et la directive @at-root, Qui place le suivant immédiatement. sélecteur ou bloc de css à la racine (il n'y aura pas de parents dans le css sorti)

Voir ceci numéro de Github pour plus de détails

3
kumarharsh