Promoting CSS reuse

Left to their own devices, a dev team of imperfect communication (i.e. all dev teams), will often reimplement the same things over and over. This is a waste of time and money and makes changes to codebases harder and harder.

Writing more emails and sending more slack messages to explain all the features and bug fixes becomes background noise. People stop paying attention to it and it drowns out the important stuff.

In my journeys working with full-stack teams, this behaviour happens most frequently when writing CSS.

Why, why, why? #

It’s a tough question and one that I’ve spent a while thinking about. A few takes:

Stylesheet organisation #

MVC frameworks are often very opinionated on where back-end code should live and what kind of code should live in each file.

But the same strong opinions haven’t really solidified for CSS. There’s no popular, dominant convention, so the confusion and chaos continues. No one’s quite sure about where different kinds of styles should live.

Designer-Developer handoff #

When developers and designers in a team aren’t the same person, there’s always friction and miscommunication handing over designs for development. Questions like “should this widget look and respond the same way as this similar looking widget on this other page?” often get don’t get asked. This results in the styles and responsive rules getting duplicated where reuse would be have been more appropriate.

Manual testing pain #

Making changes to reusable CSS components usually involves a manual process of eyeballing any page that that component is used on. Contrast this with code lower down the stack, that can be kept in check with automated tests.

Let’s say you’re working on a big site and it’s your job to add a sweet click animation to the button on the submit order page. You’ve got to edit the button styles that are used pretty much on every page across the site. A small bead of sweat drips down your forehead as you make your change. Then you have a “great” idea:

“Maybe it’s easier to duplicate the button CSS, give it another class name, make my changes and then use it on the order submit page. No worrying about checking the whole site, if it’s only used on one page.”

A month passes. One morning a QA tester spots a bad compatibility issue with the original button in a well-represented browser. A fix goes in that afternoon, but unfortunately the dev doesn’t spot your duplicated submit order button. It goes unfixed, silently broken until someone eventually notices. BAD.

Solutions? #

Promoting reuse of styles is a tricky problem, with no obvious silver bullet. But I’ve a few ideas that can help:

Build a UI Kit #

UI kits have many names (style guides, design systems, kitchen sinks, etc) but the purpose is pretty much the same: a single reference page that displays all the reusable visual elements in a project. Kind of like the Bootstrap docs, developers can look for what components they need and copy + paste code snippets.

For templating languages (e.g. Blade, Twig, ERB), I find it best to use partials for each UI kit item and document the required arguments. That way, should an item’s underlying layout change, everything updates seamlessly. No searching for every single use of that item across your whole codebase.

For JS components (as seen in React and Vue.js), a code snippet showing how the component should be initialised is important. You don’t want devs copy and pasting the raw HTML from the DOM. Document each prop. Is it required? What arg types does it accept? Etc.

Decide on a CSS architecture #

Every developer shouldn’t need to know about every style in a codebase. But everyone on a team should have a common understanding about where different stylesheets live. If visual changes are being made, it should be clear from the type of changes which stylesheets need changing and where new stylesheets should go.

If everyone’s on the same page, it’s less likely a developer will miss existing reusable styles simply because they didn’t know where to look.

An architecture that I’ve come across recently that seems to be getting a toehold is Inverted-Triangle CSS (ITCSS). Each of it’s categories represents a file directory in which stylesheets live. The “inverted-triangle” bit of the name comes from the graph below. The width of the triangle refers to the breadth of the styles i.e. the proportion of elements affected. The height refers to the style specificities, the ones at the bottom are the most specific, therefore have the power to override the styles in the categories above them.

In SCSS/SASS land, these are how the ITCSS categories translate:

The categories vary depending on where you read about ITCSS but the specific names you give them isn’t important. The important thing is that you get your team talking the same language on the front-end.

Loadsa stylesheets #

One of the nice things about preprocessors is the ability to split up your CSS into different files and have them concatenated into just one for your users. Nicely separated stylesheets without tons of HTTP requests to get them.

But another, oft forgotten advantage is that it makes existing styles way more discoverable. If you have a CSS file per widget/mixin/BEM block/whatever, when your dev colleague looks in their code editor’s file explorer, they’ll see all the different styles that already exist. As the lazy developer that I am, if I need to style a button and I see a _button.scss file, you KNOW I’m going to be looking in there.

Contrast this with a codebase where all the styles are in a single styles.css file. Nobody wants to go scrolling through a two thousand line file searching for a style that might not even exist. Easier to just chuck some more styles at the bottom of the file whilst laughing maniacally.

So long story short, I’d definitely recommend adding a liberal number of stylesheet files to your projects, even if the majority are only 3 or 4 lines long. Making them discoverable is a key part of style reuse.

Get designers on the reuse bandwagon #

Developing reusable styles is much easier if designers design in a modular way and intentionally reuse existing visual elements. If widgets in new designs don’t obviously represent existing elements, then depending on the developer, there’s about a 50/50 chance they will reimplement styles and send reusability flying out the window.

Therefore it’s dead important to encourage designers to look around and see what’s already available to them (something good ones will already do). Getting designers onboard should naturally permutate reusability through to the development process when things are handed over. It will also have the win-win benefit of speeding up build time by reusing instead of rebuilding.

Summary #

  1. Build and maintain a living UI kit.
  2. Agree on a CSS architecture with your team.
  3. Focus on making reusable CSS discoverable.
  4. Bake reusability into your whole team.