The following is a guest post by Tom Genoni. Tom built an open source Chrome Extension for analyzing CSS. I’ll let him introduce it.
It’s a new web project. You’re starting from scratch. The front end is going to be clean and orderly. You’ve set your defaults. Your CSS files are organized. You’ve got a system! This time will be different. What could possibly go wrong?
If this sounds familiar then you know how it usually ends: slowly, inevitably, the code starts to balloon and you feel the control slipping away. It becomes complex and intertwined. You’re overriding styles, naming is inconsistent, magic numbers and hacks abound. Older code is hard to parse, poorly documented, and good luck getting new coworkers to understand it. Bugs start to appear. Damn. Better just throw more CSS at it.
Determined to avoid this fate, I researched refactoring techniques, emerging best practices, and eventually built CSS Dig. In this post, I’ll highlight three areas where CSS Dig can help and provide some refactoring tips.
Start The Audit
In Nicolle Sullivan’s presentation about her refactor of Trulia she recommends taking screenshots of every nook and cranny of your site and grouping the design elements together to see the universe of font sizes, buttons, backgrounds, borders, etc. This exercise alone often surfaces a lot inconsistencies (and a fair amount of groaning) and provides a starting point for standardization.
After realizing that, yeah, we have too many button variations, the next step is to “grep your styles”: scrutinize your CSS the same way and you’ll often find a wide range of properties and values that are candidates for consolidation. This is where CSS Dig can help.
After installing the Chrome Extension you’ll see its icon in the upper-right corner of your browser. Navigate to a site you’d like to inspect and click the icon. A few caveats:
- On sites with lots of CSS, and depending on your connection speed, it can take a few seconds for CSS Dig to complete.
- Sites with strict “Content Security Policies” can cause CSS Dig to fail. For example, facebook.com and github.com.
- CSS referenced by
@import
is ignored. It’s considered a bad practice and it seems most sites now avoid it.
Speed Things Up
The first thing you’ll see is a dialog listing all the CSS files and style blocks found on that page. Note that some remote files, like font providers, are not accessible and will be listed as “Undiggable”. You can disable items, like third-party libraries, you don’t want included in the analysis but before you “Start Digging” take a good look at the list. Reducing http requests is the number one performance rule so combining CSS into fewer files is a good place to start.

Once you’ve picked the CSS you’d like to examine click “Start Digging” and you’ll be presented with the main CSS Dig screen. On the left you’ll see the properties and their counts. Clicking on these reveals the actual declarations used in the CSS. And clicking on the individual declarations isolates the rule sets in the right column.
Too Many Colors
One of the first things I like to examine are the colors. High numbers here are often the harbinger of problems in other areas. A while back I ran CSS Dig on huffingtonpost.com. They’ve since cleaned things up a bit but at the time this is what they were working with:
Different websites have different needs and constraints — but contrast that with the colors from apple.com:
Because CSS Dig shows you the number of times a color was used, you can pretty quickly identify which ones to consolidate around. Pick a dominant blue (or red or green) and make it the default. If you’re using a preprocessor create variables and stick to them. Your users will get a more consistent experience and it’ll be easier for you to maintain. Sass maps are great for this.
$ui-color: (
brand : #0081BA,
brand-light : #9ACCE2,
brand-dark : #036,
bad-news : #C60C0C,
good-news : #97C70A
);
And then referenced a color using:
.foo {
color: map-get($ui-color, brand);
}
Spacing
Other areas for standardization are paddings and margins. It’s not uncommon to have a wide spread of values, sometimes in different units, especially when different teams are working on separate parts of a site. But when components have to mix and match, inconsistencies can quickly become apparent.
One way to address this is by setting a global spacing grid that applies to all elements (with the occasional exception). In the UI library at Optimizely we use a spacing unit, currently at 10px, and all component spacing is based on that. This helps to exclude “magic numbers” yet gives some discretion to the CSS author.
For example, the following code:
.foo {
padding: spacer(1);
margin: spacer(1.5) 0;
}
compiles to:
.foo {
padding: 10px;
margin: 15px 0;
}
using:
@function spacer($value) {
@if ($value * 2) % 1 != 0 {
@warn 'Spacer value must be a multiple of 0.5';
@return 'Spacer value must be a multiple of 0.5';
} @else {
@return $spacer-unit * $value;
}
}
If our spacer function sees a value that’s not an increment of 0.5, it returns an error. There’s nothing preventing the author from using a hard-coded number, but exceptions can be discussed in a code review. I’ve found this frequently creates serendipitous harmony across components.
Specificity Wars
When Sass was gaining popularity it was not uncommon to see developers attempt to match the nested structure of the HTML they were styling. It does seem like a good idea. I tried it. But it turns out that creates all sorts of complications and it’s now frowned upon.
Among the pains it exacerbates is the long-standing struggle with CSS specificity. Overriding long selectors in an effort to reuse a highly-specific component is a confusing and annoying experience, often resulting in more selectors and (gasp) !important
rules and code you hope you never have to explain to anyone.

In the Selectors tab of a CSS Dig report, you’ll see all the selectors listed with options to sort by length and specificity. These are calculated using Keegan Street’s Specificity Calculator. This will help identify potential selector time bombs and, hopefully, begin the process of making the styles less nested, more resuable, and easier to maintain. I also recommend using CSS Specificity Graph Generator to get a bird’s eye view of your code.
Keep Going
If after taking a look at your own code you find you want to do a deeper refactor, here are a few more steps to consider.
- Pick a short code name for the refactor. This helps gives the project significance and, more importantly, provides a way to namespace new classes. At Optimizely we’re using
lego-
as a prefix for all classes (yes, I know, super original name) but it’s been invaluable in providing clear a separation between new and old classes. - Adopt a modular, object-oriented approach, like BassCSS, SMACSS, or Harry Roberts‘ upcoming refresh of his Inuitcss. This has greatly reduced the amount of new code we write and has speed up development time considerably.
- Use a linter (like CSS lint or SCSS-lint). This will automatically enforce a long list of common code standardizations, keeping your code clean and consistent.
Contribute
The CSS Dig source code is available on GitHub. Your suggestions, requests, and bug reports are welcomed.
Also, I work at Optimizely — check us out. We’re working on some interesting things.
How did you get a chart of the colors used on a site? I’m not seeing that in your CSS dig extension.
Hi Tim, CSS Dig doesn’t have a view like that (although maybe it should). I just manually copied the HTML of the results and manipulated it a bit. If you’d like to see a grouping like that I suggest http://cssstats.com/ .
I switched to a free Bootstrap theme for my blog, and can see what you mean by standardization.
*.background-color has 18
while
background-color has 313 !! (though some of them are used many times, I see what you point out by too many shades/tints of blue).
To add to confusion, both html codes and rgb codes are used.
:-(
Guess I have to manually clean it up.
Thank you for the great insight.
This is pretty cool, thanks for creating it Tom. I like how it sees
#333333
different from#333
different from#333 !important
. Makes it easier to debug.One thing that threw me off though is the
{ font-weight: bold; { margin-bottom: 10px; }
in the code preview pane after clicking some properties. Some kind of false positive i guess. Also, if you click the extension button again when its already open, it will overlay white with no way to continue/close (Chrome 41.0.2272.118 m). Not nitpicking, just figured you would wanna know.Hi DH, glad you like it. To your first question I would run your CSS through a validator. I’ve found the root of most issues in the code preview window stem from something missing in the source CSS. If there are no validator errors please open an issue on Github and include the URL you’re testing. To your second item, yes, that’s a known bug. I need to tackle that one sooner or later.
The information the tool offers is valuable, however, when used on a single page giant web app, it is repeatedly becoming unresponsive. This is the specific type of use that really needs an audit tool such as this.
Perhaps there is a way to offer inputting settings to narrow down the scope into bite sized pieces to prevent the unresponsive errors.
My current project has 72K lines of CSS and ballooning. I need this tool to respond.
Sorry to hear it’s not responsive on your site. What URL are you trying to test? If I can figure how to prevent slowness with very high CSS line counts I’ll update the extension. You could try out the Python version of CSS Dig or maybe http://cssstats.com/.
The application is not live yet. If it was, I would not be able to share it for security reasons.
One of my current tasks for auditing the CSS is to look for a specific selector and finding all css that uses it and alters the styling. I hope to see every style using a class selector for example “.specificSelectorInAudit”. Perhaps there is a way for CSS Dig to allow narrowing down to a set audit subject.
I started out doing this using a spreadsheet and I’m realizing it is a nightmare manually.
Single page web applications are only becoming more complex. Some like the one I’m working on have a large number of developers. Tools for auditing will be necessary.
I will be trying to uncheck all of the third party library CSS files using CSS Dig to see if the reduction is enough for it to respond. If that does not help, I’ll make an attempt to figure out the python version.