One of the most relieving developments in modern front-end development has been the move to componentized architecture — that is, thinking about and producing code in which markup, presentation, and business logic are bundled together structurally and/or functionally. We’ve seen this in the extreme popularity of React and the growing interest in web components (and web component-based frameworks like Polymer). The other major players in the JS framework space, such as Ember and Angular, have recognized the importance of this move and incorporated variants of the concept into their libraries as well.

This was a crux in the realm of modern front-end development, and we’re only beginning to see the extent to which this paradigm will be pushed.

It’s important to recognize the massive benefits we reap by using component-based architectures. Not only do components inherently lend themselves to concepts like code reuse and reusability; they also lend nicely to something even more important for us as developers: they reduce cognitive overhead, cyclomatic complexity, and the necessity that we constantly context-shift, tracing through any number of separate JS, HTML, and CSS files in order to specify dependencies, integrate markup/presentation/business logic, and debug.

It cannot be overstated how important this is. If you find yourself doubting the importance of an architecture in which the aforementioned reductions are accounted for, think back to the gnarliest Angular 1.x project you ever worked on. Recall having to trace through a labyrinth of HTML attributes, controller and directive names, filenames (often complete misnomers, given the controllers and directives they contain), module dependencies… Take a moment to close your eyes and visualize what the dependency graph of such an application might look like. I’d imagine “World’s Largest Ball of Twine” might be a suitable name for such a graph.

Now, given the rise of component-based architecture, particularly in the realm of JS, and the rampant popularity of component-based frameworks, we’re beginning to see similar concepts leak over into the CSS world. The community is champing at the bit for solutions that make our code easier to structure, easier to write, and easier to trace. Additionally, we’ve begun to tear down some of the preconceived notions we’ve had about CSS for decades — namely, the age-old mindset that HTML should never contain information about presentation.

Forward-thinking frameworks and libraries are riding this wave by utilizing patterns we mentioned above: the Atomic/Functional/Utility patterns that have grown in popularity over the past year or two. Tachyons, BassCSS, and my own framework, Nuclide, exemplify this.

Information can, of course, be found on the websites of each of the aforementioned projects’ websites, but to summarize: we’ll use a number of single-property CSS classes, all of the same minimal specificity, as simple, single-purpose building blocks with which to construct UI components. A contrived example of this via the Tachyons classes might look as such:

<section class="mw5 mw7-ns center bg-light-gray pa3 ph5-ns">

<!-- some content -->

</section>

Now, after you’ve overcome your disgust at the presence of so many presentational classes within HTML, let’s discuss the pros of this particular approach:

Highly-declarative HTML means we can approximate what this element looks like without even having to look at our stylesheets

Use of flat list of classes means we never have to be concerned about specificity wars or overrides

Elimination of context-based CSS means we can properly plan and execute our architecture following modern best practices: modularity, reusability, and performance

If we use this approach for the majority of our page elements, we can get by with an incredibly small amount of CSS across our site — just our reusable, composable Atomic classes (plus whatever gross, one-off stuff we have to write, as often happens on any given project)

Hey, these benefits are pretty great, right?!

Well, it’s not all peaches and cream. Let’s also consider the cons:

Responsive design isn’t exactly a cakewalk given this model. Tachyons uses additional namespaced classes to indicate media query-enveloped classes — this effectively means we need to duplicate ALL of our Atomic classes for every breakpoint. Additionally, there’s cognitive overhead associated with having our base, mobile-first classes interspersed with our media queried classes; imagine having three or more breakpoints with a large number of stylistic changes on a given component

Pseudo-classes can’t inherently be covered using this model. How would we implement hover or active states?

Pseudo-elements can’t inherently be covered using this model. How would we implement styling on :before or :after elements?

Conceptually, it’s getting there. However, we can do better.

Shit’s about to get weird.