(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
spotlights, 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.