Written by Harry Roberts on CSS Wizardry.
N.B. All code can now be licensed under the permissive MIT license. Read more about licensing CSS Wizardry code samples…
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…
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 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:
$ 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.
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.
Obviously you need some kind of rules and criteria:
shame.css
.shame.css
up when you have some down time.
/**
* 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;
}
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.
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.
N.B. All code can now be licensed under the permissive MIT license. Read more about licensing CSS Wizardry code samples…
Harry Roberts is an independent consultant web performance engineer. He helps companies of all shapes and sizes find and fix site speed issues.
Hi there, I’m Harry Roberts. I am an award-winning Consultant Web Performance Engineer, designer, developer, writer, and speaker from the UK. I write, Tweet, speak, and share code about measuring and improving site-speed. You should hire me.
You can now find me on Mastodon.
I help teams achieve class-leading web performance, providing consultancy, guidance, and hands-on expertise.
I specialise in tackling complex, large-scale projects where speed, scalability, and reliability are critical to success.