Sass combining parent using ampersand (&) with type selectors
I am having trouble with nesting in Sass. Say I have the following HTML:
<p href="#" class="item">Text</p>
<p href="#" class="item">Text</p>
<a href="#" class="item">Link</a>
When I try to nest my styles in the following I get a compiling error:
.item {
color: black;
a& {
color:blue;
}
}
How do I reference a type selector before the parent selector when it is part of the same element?
Solution 1:
As Kumar points out, this has been possible since Sass 3.3.0.rc.1 (Maptastic Maple)
.
The @at-root directive causes one or more rules to be emitted at the root of the document, rather than being nested beneath their parent selectors.
We can combine the @at-root
directive along with interpolation #{}
to arrive at the intended outcome.
SASS
.item {
color: black;
@at-root {
a#{&} {
color:blue;
}
}
}
// Can also be written like this.
.item {
color: black;
@at-root a#{&} {
color:blue;
}
}
Output CSS
.item {
color: black;
}
a.item {
color: blue;
}
Solution 2:
The @at-root
-only method will not solve the problem if you intend to extend the closest selector up the chain. As an example:
#id > .element {
@at-root div#{&} {
color: blue;
}
}
Will compile to:
div#id > .element {
color: blue;
}
What if you need to join your tag to .element
instead of #id
?
There's a function in Sass called selector-unify()
that solves this. Using this with @at-root
it is possible to target .element
.
#id > .element {
@at-root #{selector-unify(&, div)} {
color: blue;
}
}
Will compile to:
#id > div.element {
color: blue;
}