Is any BEM entity allowed to modify any other entity?
Specifically, is an element allowed to modify another entity?
Consider the following example, where a modifier positions another block - in this case, we have a close
block for close gadgets on dialogs etc. and a modal
block for modal dialogs:
<div class="modal">
<header class="modal__header">
Title goes here...
<span class="close"></span>
</header>
<section class="modal__body">
Content goes here...
</section>
</div>
The close
block itself doesn't have margin/padding/positioning, because we want it to be reusable in different contexts.
In the context of a modal
, the close
gadget needs to be positioned properly though, and normally I'd just do this:
.modal__header .close {
position: absolute;
right: 7px;
top: 4px;
}
I've been told this goes against BEM, and instead I should add a modal__close
element, and mark it up as:
<div class="modal">
<header class="modal__header">
Title goes here...
<span class="close modal__close"></span>
</header>
<section class="modal__body">
Content goes here...
</section>
</div>
My argument is that the close modal__close
combination is meaningless, because:
- The
modal__close
element doesn't work on it's own
- If you forget to add
modal__close
, the close
gadget will break the design.
- The
close
block should always and only occur precisely once in a modal__header
.
In other words, the close modal__close
combination is meaningless since, in the context of a modal, there is no use-case for either close
or modal__close
without the other.
I'm struggling to understand precisely what BEM is - if it's a naming convention and a set of patterns, the way I understand patterns (as a programmer) is as language used to describe what you've implemented; but not as decision-making drivers that should dictate what you implement.
In the same sense, I feel that BEM naming is valuable as a convention for describing the logical relationships between CSS classes - and shouldn't be viewed as a set of rules that dictate how you structure your CSS.
In fact, for this modal example, I'd like to go even simpler and drop the modal elements:
<div class="modal">
<header>
Title goes here...
<span class="close modal__close"></span>
</header>
<section>
Content goes here...
</section>
</div>
And just write CSS like this:
.modal > header {
...
}
.modal > section {
...
}
Again, my argument is that the immediate header
and section
elements of a .modal
are clearly already elements in the HTML sense, and there is no other use-case for header
or section
elements as immediately children of a .modal
except as the header and body elements of that modal.
Overriding these with a modifier, despite the higher specificity, is literally almost the same thing - e.g. this:
.modal--large > header { ... }
Versus this:
.modal--large .modal--header { ... }
I don't understand how either of these is any better or worse, beside the specificity argument, which seems inconsequential here, since you'll need to specify the modifier and target the header element somehow, for any rule that affects anything below it.
In fact, the first option seems like a generally safer choice in a lot of cases, such as, for example, panels within panels:
<div class="panel panel--red">
<header>...</header>
<section>
Some content here, and another panel:
<div class="panel">
...
</div>
</section>
</div>
In this example, I'd like to target .panel--red > section
to make it red - and this won't and should not affect the color of the nested panel inside it.
Contrast this with:
<div class="panel panel--red">
<header class="panel__header">...</header>
<section class="panel__body">
Some content here, and another panel:
<div class="panel">
...
</div>
</section>
</div>
If you target the panel body with a selector like .panel--red .panel__body
to affect the color, this will cascade to any nested panel__body
elements and override their default color, which is not what was intended.
Bottom line: should you think for yourself and implement your CSS as needed - or should you apply BEM patterns slavishly and set aside your own judgment?
Do my examples go against BEM in any way?