SASS + BEM is pretty much a match made in heaven most of the time, but a common struggle of mine is understand how to best define BEM modifiers on an element that affects it's child elements while using SASS parent selectors.
I have the following component defined in SASS using BEM style syntax:
.card {
background-color: #FFF;
&__value {
font-size: 2em;
color: #000;
}
}
This works well because of SASS's parent selector. It keeps relevant code organized and self-contained.
But when I need to add a modifier that alters a child element using a parent selector, the idea quickly falls apart:
.card {
padding: 2em;
&__value {
font-size: 1.5em;
color: #000;
}
&--big {
padding: 2.5em;
&__value { // Is this going to work?
font-size: 3em;
}
}
}
Nope. It generates this:
.card {
padding: 2em;
}
.card__value {
font-size: 1.5em;
color: #000;
}
.card--big {
padding: 2.5em;
}
.card--big__value { // Wrong
font-size: 3em;
}
It would make more sense to somehow get this selector:
.card--big .card__value {
font-size: 3em;
}
The reason for this, is so you can simply add a modifier to the top level element and have it affect any or all of the child elements.
I've tried a couple approaches:
Use two structures
.card {
padding: 2em;
&__value {
font-size: 1.5em;
color: #000;
}
}
.card--big {
padding: 2.5em;
&__value {
font-size: 3em;
}
}
This works (especially in this simplified demonstration) but in a more complicated set of components with many modifiers this can be a potential pain to maintain and keep bug free. Also, it would nice to continue to use SASS parent selectors if possible.
Use a variable for the element
.card {
$component: &; // Set the variable here
padding: 2em;
&__value {
font-size: 1.5em;
color: #000;
}
&--big {
padding: 2.5em;
#{$component}__value { // Use it here
font-size: 3em;
}
}
}
This works well. But it seems kind of silly to have to define the element as a variable. Maybe it's the only real way to do this... I'm not sure. Are there better options to how to structure this?