(Consider skipping to the live example.)
You’re probably familiar with abstract base classes in object-oriented languages. In a nutshell, abstract base classes let you set up some expectations of what a derived class must do, but nobody can actually instantiate instances of the base class. One needs to create a derived class, then create objects that are instances of that derived class.
A similar idea came to me while I was working in BEM.
I was working on something that I called a “spotlight” block that you may remember from earlier. Here’s what they look like in the HTML source:
<div class='spotlight'>
<div class='spotlight__image'></div>
<div class='spotlight__verbiage'>Mmm, meat.</div>
</div>
.spotlight__image
’s background is supposed to be a flavor image. .spotlight__verbiage
, as shown, is supposed to have text in it.
I wanted to be able to have both image-on-left and image-on-right spotlight
s, but I also wanted to be able to keep the source order the same for both.
On very narrow viewports, my plan was to shrink the width of .spotlight__image
to just a tiny sliver, so I wasn’t concerned with rotating the block 90° to put the image on top.
The obvious way to do this sort of thing would be to have two main styles:
.spotlight
(implicitly puts the image on the left).spotlight--image-last
(flips the text/image order)
With this arrangement, I ended up setting most style adjustments (padding, etc.) on spotlight
and undoing them on .spotlight--image-last
. The undoing parts of .spotlight--image-last
turned out to be my, um, undoing; order flips using flexbox tend to be weirdly asymmetrical.
Eventually, I settled on requiring users of .spotlight
to explicitly pick an order. A user could use either:
<div class='spotlight spotlight--image-first'>
<div class='spotlight spotlight--image-last'>
but I wouldn’t make any guarantees on what it should look like if there were no with-modifier (the part after the --
) class on the element.
A worked example would be worth at least a thousand words at this point, so go see a live example of this in action. Beats being remotely tempted to undo things with :not()
and similar.