Promoting CSS reuse

Left to their own devices, a dev team of imper­fect com­mu­nic­a­tion (i.e. all dev teams), will often reim­ple­ment the same things over and over. This is a waste of time and money and makes changes to code­bases harder and harder.

Writ­ing more emails and send­ing more slack mes­sages to explain all the fea­tures and bug fixes becomes back­ground noise. People stop pay­ing atten­tion to it and it drowns out the import­ant stuff.

In my jour­neys work­ing with full-stack teams, this beha­viour hap­pens most fre­quently when writ­ing CSS.

Why, why, why? #

It’s a tough ques­tion and one that I’ve spent a while think­ing about. A few takes:

Stylesheet organ­isa­tion #

MVC frame­works are often very opin­ion­ated on where back-end code should live and what kind of code should live in each file.

But the same strong opin­ions haven’t really solid­i­fied for CSS. There’s no pop­u­lar, dom­in­ant con­ven­tion, so the con­fu­sion and chaos con­tin­ues. No one’s quite sure about where dif­fer­ent kinds of styles should live.

Design­er-Developer han­doff #

When developers and design­ers in a team aren’t the same per­son, there’s always fric­tion and mis­com­mu­nic­a­tion hand­ing over designs for devel­op­ment. Ques­tions like​“should this wid­get look and respond the same way as this sim­il­ar look­ing wid­get on this oth­er page?” often get don’t get asked. This res­ults in the styles and respons­ive rules get­ting duplic­ated where reuse would be have been more appropriate.

Manu­al test­ing pain #

Mak­ing changes to reusable CSS com­pon­ents usu­ally involves a manu­al pro­cess of eye­balling any page that that com­pon­ent is used on. Con­trast this with code lower down the stack, that can be kept in check with auto­mated tests.

Let’s say you’re work­ing on a big site and it’s your job to add a sweet click anim­a­tion to the but­ton on the sub­mit order page. You’ve got to edit the but­ton styles that are used pretty much on every page across the site. A small bead of sweat drips down your fore­head as you make your change. Then you have a​“great” idea:

Maybe it’s easi­er to duplic­ate the but­ton CSS, give it anoth­er class name, make my changes and then use it on the order sub­mit page. No wor­ry­ing about check­ing the whole site, if it’s only used on one page.”

A month passes. One morn­ing a QA test­er spots a bad com­pat­ib­il­ity issue with the ori­gin­al but­ton in a well-rep­res­en­ted browser. A fix goes in that after­noon, but unfor­tu­nately the dev doesn’t spot your duplic­ated sub­mit order but­ton. It goes unfixed, silently broken until someone even­tu­ally notices. BAD.

Solu­tions? #

Pro­mot­ing reuse of styles is a tricky prob­lem, with no obvi­ous sil­ver bul­let. But I’ve a few ideas that can help:

Build a UI Kit #

UI kits have many names (style guides, design sys­tems, kit­chen sinks, etc) but the pur­pose is pretty much the same: a single ref­er­ence page that dis­plays all the reusable visu­al ele­ments in a pro­ject. Kind of like the Boot­strap docs, developers can look for what com­pon­ents they need and copy + paste code snippets.

For tem­plat­ing lan­guages (e.g. Blade, Twig, ERB), I find it best to use par­tials for each UI kit item and doc­u­ment the required argu­ments. That way, should an item’s under­ly­ing lay­out change, everything updates seam­lessly. No search­ing for every single use of that item across your whole codebase.

For JS com­pon­ents (as seen in React and Vue.js), a code snip­pet show­ing how the com­pon­ent should be ini­tial­ised is import­ant. You don’t want devs copy and past­ing the raw HTML from the DOM. Doc­u­ment each prop. Is it required? What arg types does it accept? Etc.

Decide on a CSS archi­tec­ture #

Every developer shouldn’t need to know about every style in a code­base. But every­one on a team should have a com­mon under­stand­ing about where dif­fer­ent stylesheets live. If visu­al changes are being made, it should be clear from the type of changes which stylesheets need chan­ging and where new stylesheets should go.

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

An archi­tec­ture that I’ve come across recently that seems to be get­ting a toe­hold is Inver­ted-Tri­angle CSS (ITC­SS). Each of it’s cat­egor­ies rep­res­ents a file dir­ect­ory in which stylesheets live. The​“inver­­ted-tri­angle” bit of the name comes from the graph below. The width of the tri­angle refers to the breadth of the styles i.e. the pro­por­tion of ele­ments affected. The height refers to the style spe­cificit­ies, the ones at the bot­tom are the most spe­cif­ic, there­fore have the power to over­ride the styles in the cat­egor­ies above them.

ITCSS Layers

In SCSS/SASS land, these are how the ITC­SS cat­egor­ies translate:

  1. Set­tings — @font-face and vari­able definitions.
  2. Tools — Mix­ins and functions.
  3. Gen­er­ic — Reset and nor­mal­izer styles.
  4. Ele­ments — Default styles for HTML ele­ments e.g. h1, p, a, etc.
  5. Objects — Related to OOC­SS Objects, these are gen­er­ic styles which effect how the page con­tent is laid out. Aes­thet­ics styles for things like col­ours and fonts shouldn’t go in here.
  6. Com­pon­ents — Styles for your wid­gets. Most applic­a­tion styles live in here.
  7. Util­it­ies — Styles for high-spe­­ci­ficity util­ity and over­ride classes. Often a dump­ing ground for dirty hacks. 👎 The cat­egor­ies vary depend­ing on where you read about ITC­SS but the spe­cif­ic names you give them isn’t import­ant. The import­ant thing is that you get your team talk­ing the same lan­guage on the front-end.

Loadsa stylesheets #

One of the nice things about pre­pro­cessors is the abil­ity to split up your CSS into dif­fer­ent files and have them con­cat­en­ated into just one for your users. Nicely sep­ar­ated stylesheets without tons of HTTP requests to get them.

But anoth­er, oft for­got­ten advant­age is that it makes exist­ing styles way more dis­cov­er­able. If you have a CSS file per widget/​mixin/​BEM block/​whatever, when your dev col­league looks in their code editor’s file explorer, they’ll see all the dif­fer­ent styles that already exist. As the lazy developer that I am, if I need to style a but­ton and I see a _button.scss file, you KNOW I’m going to be look­ing in there.

Con­trast this with a code­base where all the styles are in a single styles.css file. Nobody wants to go scrolling through a two thou­sand line file search­ing for a style that might not even exist. Easi­er to just chuck some more styles at the bot­tom of the file whilst laugh­ing maniacally. 

So long story short, I’d def­in­itely recom­mend adding a lib­er­al num­ber of stylesheet files to your pro­jects, even if the major­ity are only 3 or 4 lines long. Mak­ing them dis­cov­er­able is a key part of style reuse.

Get design­ers on the reuse band­wag­on #

Devel­op­ing reusable styles is much easi­er if design­ers design in a mod­u­lar way and inten­tion­ally reuse exist­ing visu­al ele­ments. If wid­gets in new designs don’t obvi­ously rep­res­ent exist­ing ele­ments, then depend­ing on the developer, there’s about a 50/50 chance they will reim­ple­ment styles and send reusab­il­ity fly­ing out the window.

There­fore it’s dead import­ant to encour­age design­ers to look around and see what’s already avail­able to them (some­thing good ones will already do). Get­ting design­ers onboard should nat­ur­ally per­mutate reusab­il­ity through to the devel­op­ment pro­cess when things are handed over. It will also have the win-win bene­fit of speed­ing up build time by reusing instead of rebuilding.

Sum­mary #

  1. Build and main­tain a liv­ing UI kit.
  2. Agree on a CSS archi­tec­ture with your team.
  3. Focus on mak­ing reusable CSS discoverable.
  4. Bake reusab­il­ity into your whole team.