Sass BEM: Avoid duplicating a modifier when an element is inside a modifier.

Is there any way to reorganize the following code snippet to get rid of the double modifier declaration?

.block { &__element { rule: value; } &--modifier { rule: value; } &--modifier & { &__element { rule: value; } } } 

Required Conclusion:

 .block { property: value; } .block--modifier { property: value; } .block--modifier .block__element { property: value; } 
+7
sass bem
source share
3 answers

Nested elements inside modifiers are a known issue . There are many workarounds.

Variable way

Save the block element in a variable.

And use it to interpolate when creating an element inside a modifier.

 .block { $block: &; &__element { property: value; } &--modifier { property: value; #{$block}__element { property: value; } } } 

See conclusion below.

Functional way

1. Create a function that returns a block element.

It will get the parent selector and cut the word to -- (which is a block). Looks like hacks, but this is the easiest way to go.

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

2. Use the interpolation function.

Which will return the name of the block, so you do not need to repeat it.

 .block { property: value; &--modifier { property: value; #{block()}__element { property: value; } } } 

See conclusion below.

Both methods will be displayed on:

 .block { property: value; } .block--modifier { property: value; } .block--modifier .block__element { property: value; } 
+12
source share

You can put a block in the &--modifier selector as follows, using the class name for the block rather than & for targeting it.

 .block { &__element { rule: value; } &--modifier { rule: value; .block { &__element { rule: value; } } } } 

However, this may not be the best BEM solution, you should consider renaming the nested block as an element of the containing block, for example .block__another-element or creating a new block.

+1
source share

You can add & next to the modifier for a solution similar to Toni's.

 .block { &__element { rule: value; } &--modifier & { rule: value; &__element { rule: value; } } } 

However, this requires .block be a root selector and not embed in any other selector.

Another possible solution. However, for most situations, I would prefer a Toni solution.

+1
source share

All Articles