Pushing BEM to the next level with Sass 3.4
Marc Mintel
559

BEM and Sass 3.4, without mixins

UPDATE: I’ve posted a follow up to this detailing a simpler syntax using no mixins or functions at all: https://medium.com/@jacksleight/bem-and-sass-without-mixins-or-functions-a2f0445f504e

Inspired by @marcmintel’s excellent article Pushing BEM to the next level with Sass 3.4, I tried to find a way to solve the element inside a modifier issue using plain class names and the parent selector (or as close to that as I could get), instead of mixins. This is what I came up with.

With this function, which is just a butchered version of Marc’s selectorToString() and getBlock():

@function b() {
$selector: str-slice(inspect(&), 2, -2);
$index: str-index($selector, '--') - 1;
@return str-slice($selector, 0, $index);
}

We can write this SCSS:

.media {
border: 1px solid;
&__content {
font-size: 10px;
}
&--large {
#{b()}__content {
font-size: 20px;
}
}
}

Which gives us this output:

.media {
border: 1px solid;
}
.media__content {
font-size: 10px;
}
.media--large .media__content {
font-size: 20px;
}

As you can see #{b()} gives you the parent selector sans-modifier, which can be combined with the element name to give the correct nested syntax.

Play with the code on SassMeister.

If you have any improvements, comments or questions feel free to contact me on twitter @jacksleight.

Show your support

Clapping shows how much you appreciated Jack Sleight’s story.