Have you seen The Grug Brained Developer? It’s an essay with a URL. It’s written like a caveman became a developer and put together a philosophy that is largely a rally against complexity. Cavemen have dumb simple brains, get it? It has good points, and I largely agree with it. The caveman angle is a clever quirk to get to read it and to stick in ol’ brain.

(If you find it hard to read, I have seen a “translation”).

I think it’s fairly easy to relate to what Grug means when it comes to back-end architecture. Sprawling systems with complex requirements, services talking to each other, APIs, third-party dependencies, data manipulation methods, etc. It’s not that front-end development doesn’t have its own complexities, but it’s less obvious to point at a bit of CSS and be like, that, that’s where the complexity got too much.

Is it over, say, 2000 lines of CSS? Is it over three levels of nested DOM per component, or 12 overall? Is selector specificity averages? Is it when browser support requirements go too far back? Is it when there are too many sources of input?

I’ve certainly known organizations that, without perhaps understanding or admitting it, are afraid of their CSS. Nobody wants to touch it because nobody is entirely sure if they are going to kick over a bar stool in another bar, as the meme goes.

Taylor Troesh on a recent Changelog podcast said:

If there is any part of your code base that is starting to scare you, it needs immediate attention. Things will just get worse if there is that one part of your code base that all of your engineers are afraid to touch, because it grows in disgustingness, everyone wants to just get in there and get out and it accumulates. You want to start thinking about how you can throw that away without breaking everything.

I don’t think Taylor was talking about CSS, but to me, it maps perfectly. CSS can get into a situation where developers are afraid to touch it. That’s one reason I’m bullish on CSS that is scoped (despite my hesitation on actual CSS @scope), like CSS modules and Shadow DOM. If you can edit CSS with reasonably high confidence that you’re not touching styles elsewhere unintentionally, that’s good.

I feel CSS nesting, which is now a native feature of CSS, helps this to some degree. Write a unique class, and everything you select in a nested way is scoped to that class without you having to repeat the class name. Plus it’s just kinda ergonomically nice. But there are rather significant gotcha’s, which admittedly I really had no idea about until reading Kilian Valkhof’s The gotchas of CSS Nesting. The order in which rules are applied can get funky, and the specificity can also be unexpected. One example from Killian:

main, #intro {
    & div {

Ends up as:

:is(main, #intro) div { ... }

Which makes it go from 0,0,1 for main div to 1,0,1 making it vastly more specific.

I’m not sure if nesting gotchas is the ultimate example of CSS complexity gone wild, but it’s just one little potential poke. I remember in the Sass heyday that people would point to @extend as a complexity code smell and they weren’t wrong.

Perhaps thanks to the scale and pervasiveness of npm, piles of questionable third-party code is another cause of complexity concern on the front-end. Michelle Barker gets into this in Reducing Complexity in Front End Development where she’s ruminating on Jack Franklin’s recent talk at All Day Hey.

A quick look in our Node modules folder quickly exposes the web of complexity within, which few of us can really fathom. A single point of failure can bring down the entire stack, like the well-worn “house of cards” metaphor.

Reducing dependencies, I’ll go out on a limb and say, is nearly always “worth it” in the sense of saving future-you headaches. Or as grug says:

one day code base understandable and grug can get work done, everything good!

next day impossible: complexity demon spirit has entered code and very dangerous situation!