17 April, 2013

shame.css

Update: I did a short interview about shame.css with .net magazine.

Something Chris Coyier, Dave Rupert and I joked about recently was the idea of a stylesheet dedicated to housing your nasty, hacky, quick-fix CSS. I’ve been thinking a lot more about it lately and I reckon it’s actually a pretty good idea; here’s why…

The problem

We all know that, no matter how hard we may try, sometimes we do need to use quick fixes, hacks and questionable techniques in our code. It happens, whether we like to admit it or not.

From using a quick overflow:hidden; instead of working out what’s actually broken our layout, to the odd !important to override some poor CSS, there are often times where we need to use less than ideal CSS in order to meet deadlines, to get something working, or to fix pressing—or even live—bugs.

Whilst this isn’t ideal, we have to do it from time to time; all of us.

The real problem, though, is that we rarely go back and tidy these things up. They slip through the cracks, get ignored, go unnoticed, and stay for good. This we do not have to do.

The problem with leaving hacks and nasty code is obvious; it’s hacky and nasty. However, other problems with leaving this code can arise… I think the most important and severe is the fact that, as soon as another developer sees that someone used !important, they feel less bad about doing the same; the next developer who comes along and sees that someone bodged something doesn’t feel too guilty about hacking something else. The first bits of bad code set a precedent and make subsequent developers feel less bad about using poor code themselves. It was like that when I got here! Give developers a clean slate and they’ll really think twice about messing it all up.

What is needed is a way of allowing these hacks when necessary, but making sure that they don’t go unnoticed and unresolved. Enter shame.css.

The solution

The idea of shame.css is that you have a totally new stylesheet reserved just for your hacky code. The code you have to write to get the release out on time, but the code that makes you ashamed.

By putting your bodges, hacks and quick-fixes in their own file you do a few things:

  1. You make them stick out like a sore thumb.
  2. You keep your ‘main’ codebase clean.
  3. You make developers aware that their hacks are made very visible.
  4. You make them easier to isolate and fix.
  5. $ git blame shame.css.

If anyone has to add a quick hack, they add it to shame.css, this means that they’re putting their hacks out there in the open; it means that they are aware that what they’re doing is hacky, it forces them to document what the problem was, how the hack fixes it, and how they might fix it for real given more time.

It means that other developers can see what hacks are being introduced, and why; it means that all the hacky bits of CSS are self contained, and it creates a self-fulfilling todo list.

It also means that you can run a $ git blame shame.css to see what was added when, and by who.

Not a blame game

You’d be forgiven for thinking the point of this whole exercise is to shame the developers (you can always pick a name other than shame.css) but it’s really not. I am well aware of (and responsible for) hacks and quick fixes; your product owner doesn’t care if you used an !important, they just want the new feature out of the door. Hacks happen, fact.

shame.css is jokingly titled to make it a little light-hearted whilst also indicating that anything in there is a bit of a shame; a shame to have to have done, a shame to pollute the codebase with and so on…

By isolating all your hacks and bodge-jobs in their own file you can really easily keep tabs on them; isolating them isn’t to shame the developers, not at all, it’s merely to make the team aware of them and make them painfully, unmissably obvious.

The rules

Obviously you need some kind of rules and criteria:

  1. If it’s a hack, it goes in shame.css.
  2. Document all hacks fully:
    1. What part of the codebase does it relate to?
    2. Why was this needed?
    3. How does this fix it?
    4. How might you fix it properly, given more time?
  3. Do not blame the developer; if they explained why they had to do it then their reasons are probably (hopefully) valid.
  4. Try and clean shame.css up when you have some down time.
    1. Even better, get a tech-debt story in which you can dedicate actual sprint time to it.

Example

/**
 * Nav specificity fix.
 *
 * Someone used an ID in the header code (`#header a{}`) which trumps the
 * nav selectors (`.site-nav a{}`). Use !important to override it until I
 * have time to refactor the header stuff.
 */
.site-nav a{
    color:#BADA55!important;
}

Implementation

Obviously, the simplest way to implement shame.css is with a preprocessor that would simply import that file. If you aren’t using a preprocessor then you’ll need to have a build process which concatenates all your stylesheets for you. The idea isn’t to make shame.css publicly viewable, so you definitely don’t want two <link /> elements for two stylesheets; shame.css simply needs incorporating into your concatenated and minified stylesheet.

Keep track of your hacks!

I really think I’m going to implement this; if not on my current project then definitely on my next one. I’d love to know if anyone else uses it, or what you think to the idea.


Did you enjoy this? Hire me!


Hi there, I’m Harry. I am a Consultant Front-end Architect, designer, developer, writer and speaker from the UK; I am available for work. I write, tweet, speak and share code about authoring and scaling CSS for big websites.