BEM (Block, Element, Modifier), the CSS discipline in which CSS components are defined in ways that clarify how they're used, has long been lamented for its verbosity. Take this example from the home page banner on the BEM advocacy site GetBEM:
.opinions-box__view-more--is-disabled {
color: gray;
}
This means that there's a high-level, class-based component, opinions-box
, with a child element (a
button, perhaps) with the class view-more
, and this is the class you apply to that button when
it's enabled.
These rule names can get absurdly long.
Personally, I find BEM to be about as unweildy as a Swiss Army Sword. It still insists that you memorize certain semantics and focus on how they interact with the rest of the world. We tried to tame the beast, but somehow, recently, it has once again gotten out of hand.
I'm relieved by things like Modular CSS and even the ShadowDOM, as unwieldy as it may be, because it
limits the amount of thinking you have to do about a component. Everything is defined in fairly
one-to-one terms; child components can have strongly isolated names, so instead of
.opinions-box__view-more
it's just .view-more
. Reducing the amount a developer has to hold in
their head to accomplish their mission has to be a valued achievment.
So imagine my dismay when, after successfully taming all this classing and nesting and stuff with Sass and Modular CSS and a host of other technologies, the designers decided to put it all back. Worse, they decided that CSS wasn't precise enough, and they had to go even more verbose in their definitions. Consider this:
--pf-v5-c-menu--m-drilled-in--c-menu__list-item--m-current-path--c-menu--ZIndex
This is from IBM's Patternfly CSS system, which they use for their
Patternfly React component library. What this specifies is the z-index
for the innermost component
of:
<menu class="pf-v5-c-menu pf-m-drilled-in">
<li class="pf-m-current-path">This thing</li>
</menu>
That is clearly a block-modifier-element-modifier sequence described there, but it can get worse. Much worse:
--pf-v5-c-form__field-group__field-group--field-group__field-group-header--after--BorderBlockStartWidth
"The top border of the :after
pseudo-element of a field group header, when it's in a field group
nested in another field group nested in a form, should be this wide." Phew. Try thinking that five
time fast.
CSS Custom Properties are amazing. In terms of the long-term readability and maintainability of large CSS projects, however, they're definitely going backward. What we need now are conventions and accompanying configurations that dictate what the parts of a CSS Custom Property are, and an ability to manipulate them independently.
Design Systems feel like a useful step, but they have one major flaw: every time you encounter one of them, you step right into the fact that they're designed for more than CSS. They want to be universal, to apply to React Native and Android Native and iOS Native and even print media. So the rules are then massaged by scripts (usually written in JavaScript) to be compatible with all the various environments in which the specified design system might be used. Design Systems also notoriously fail to embrace all of what CSS specifies, which is why so many CSS libraries backed by a design system are full of concrete specifications, which then read the CSS Custom Properties for the characteristics that can be specified in a design system.
Component libraries based in Modular CSS or the ShadowDOM sought to prevent developer's cognitive overload by limiting the size and scope of how much one human brain would have to hold to make sense of a given component. The Design System naming schemes, simply by
By creating a circumstance where one has to understand 100+ character "words," one per component characteristic (or, worse, "sub-characteristic" when talking about the timing of a transitions or a specific aspect of a drop shadow), just to do your job, is heading in the wrong direction.