The &
character in Sass is unique in that it represents the current selector. It changes as you nest. Let’s say you are nested, but you want access to a selector back up the nesting a bit. The trick is to cache & and use it deeper in the nesting. Like:
.parent {
$this: &;
&--elem {
display: inline-block;
&:hover,
#{$this}__variation--active & {
background: red;
}
}
}
Which compiles to:
.parent--elem {
display: inline-block;
}
.parent--elem:hover, .parent__variation--active .parent--elem {
background: red;
}
(Thanks to Sergey Kovalenko for sending in this trick!)
Meaning it allowed you to use .parent
and .parent--elem
within a selector at the same time. A little esoteric, but might be useful sometimes. Sort of avoids situations where you might need to use @at-root to back out all the way and re-make selectors.
Sergey’s gist has examples that are BEM-based:
<ul class="pagination">
<li class="pagination__item">
<a class="pagination__link" href="#">
Page 1
</a>
</li>
<li class="pagination__item pagination__item--active">
<a class="pagination__link" href="#">
Page 2
</a>
</li>
</ul>
$gray-very-light: #ccc;
.pagination {
display: flex;
padding: 0;
list-style: none;
$this: &;
&__item {
border: 1px solid $gray-very-light;
& + & {
margin-left: .5rem;
}
}
&__link {
display: block;
padding: .25rem .5rem;
text-decoration: none;
&:hover,
#{$this}__item--active & { // Here we get .pagination from $this variable
background-color: $gray-very-light;
}
}
}
Output:
.pagination {
display: flex;
padding: 0;
list-style: none;
}
.pagination__item {
border: 1px solid #ccc;
}
.pagination__item + .pagination__item {
margin-left: .5rem;
}
.pagination__link {
display: block;
padding: .25rem .5rem;
text-decoration: none;
}
.pagination__link:hover,
.pagination__item--active .pagination__link {
background-color: #ccc;
}
Simple and effective, great find Sergey!
That’s pretty sweet!
Neat trick. Although, I’d probably name the selector something like
$parentSelector
instead of$this
, which doesn’t convey much information.This is really nice. I’ve been working on a LESS project recently and it seems like this is not possible there. Unfortunately.
You absolutely can do this with less, it’s just a little different,
at the root of your class declare a variable under your root selector ie:
I believe it’s something like that
What value does this provide over repeating the base class name, i.e. “.parent__variation–active &”?
This trick are not work anymore, I try it and got result
Invalid CSS after "&": expected selector
, so you must set name class to variable.But i dont get the documentation that tell about this breaking change.