BEM class selectors and the Sass ampersand
The Sass ampersand is incredibly useful in building selectors based on the parent selector, but it has a limitation. Take the following nested BEM-style selectors:
Code language: Sass
.component {
// A BEM modifier.
&--reversed {
background: white;
border-color: lightgray;
// Target a descendent only when the parent has the modifier? Not exactly...
&__child-element {
background: rebeccapurple;
}
}
}
The linked post explains the problem:
Wait, why is this not working? The problem is that the
&
has a scope of.component--reversed
, so&__child-element
compiles to.component--reversed__child-element
, which doesn’t [exist] in the markup.
The fix is to save the &
to a variable in the parent and use that in the child selector:
Code language: Sass
.component {
// Save the current value of & as $self.
$self: &;
&--reversed {
background: white;
border-color: lightgray;
// Print $self in place of & to get the correct scope of the parent above.
#{$self}__child-element {
background: rebeccapurple;
}
}
}
The compiled CSS for that element is now
.component--reversed .component__child-element
[.]