Reputation: 9614
Let's say I have the following CSS for a generic list component, using BEM and SCSS:
.list {
&__item {
&:not(:last-child) {
margin-right: .3em;
}
}
}
I want to add a modifier that can make the list vertical, like so:
.list--vertical {
display: flex;
flex-direction: column;
}
My problem arises when I think about the margin for list__item elements. For vertical lists, I want my margin on the bottom, not right of each item. If I understood BEM correctly, I cannot modify the style of list__item based on the modifer of list, is that correct?
To be more precise, this is what I want to do:
.list--vertical {
display: flex;
flex-direction: column;
.list__item {
&:not(:last-child) {
margin-bottom: .3em;
margin-right: 0;
}
}
}
What is the accepted way of dealing with this using BEM? Another modifier for list__item that handles the margin? Another block entirely for vertical lists?
Upvotes: 6
Views: 962
Reputation: 179264
What is the accepted way of dealing with this using BEM?
Depends on what version of BEM you're using. I use a variant of the pre-spec concept of BEM, which means that you'll have different answers if you follow bem.info.
Modifiers should be attached to the element they modify. Modifying a block, however, allows the modifier to be inherited by child elements:
<div class="foo foo--example">
<div class="foo__bar foo--example__bar">...</div>
<div>
This gets messy when child elements have modifiers as well:
<div class="foo foo--example">
<div class="
foo__bar
foo--example__bar
foo__bar--another-example
foo--example__bar--another-example">...</div>
<div>
This form of BEM syntax is quite verbose. It's best used on generated code.
I use LESS for CSS preprocessing, so my BEM code often looks like:
.foo {
...
&__bar {
...
}
}
With modifiers it becomes:
.foo {
...
&__bar {
...
}
&--example {
...
&__bar {
...
}
}
}
This enforces that the cascade is in the proper order and that all selectors continue to have exactly one class.
Upvotes: 2