Static Analysis For CSS

by Brian Rinaldi on January 27, 2014

The modern web is always changing, and this article is more than two years old.

By Toby Ho

Static analysis involves analyzing, rather than executing, source code, a process that is typically automated. Recently, I’ve had fun writing about static analysis for Javascript. This time, we’ll do something that’s similar but different – static analysis for CSS.

The CSS Module

The library we’ll use to help perform the static analysis is simply called css and it can be found on npm. So, assuming you already have Node.js installed, you just need to do npm install css to install it. It contains both a parser and an emitter.

Parsing CSS

Let’s say you have a sample.css file:

.btn:focus {
  color: #333333;
  text-decoration: none;

To parse it using the css library from above, you’d write this:

var css = require('css');
var fs = require('fs');
var code = fs.readFileSync('sample.css') + '';
var ast = css.parse(code);
console.log(JSON.stringify(ast, null, '  '));

When you run this code, you’ll see its abstract syntax tree (AST) printed to the console:

  "type": "stylesheet",
  "stylesheet": {
    "rules": [
        "type": "rule",
        "selectors": [
        "declarations": [
            "type": "declaration",
            "property": "color",
            "value": "#333333"
            "type": "declaration",
            "property": "text-decoration",
            "value": "none"

Modifying the AST

Let’s say that, for whatever reason, we want all the rules in the CSS file to only take effect for elements which are descendants of certain elements – specified by the class root. We can do that by prefixing every selector of every rule with .root.

  for (var i = 0; i < rule.selectors.length; i++){
    rule.selectors[i] = '.root ' + rule.selectors[i];

Emitting the Modified CSS

Now that we have modified the AST, we can use the stringify() method to regenerate the CSS from it:


And the output is:

.root .btn:hover,
.root .btn:focus {
  color: #333333;
  text-decoration: none;

Yay! Easy, right?

See Also:  Getting started with Redux using the Mullet Stack

Other Possibilities

What are other interesting things you can do? You are limited only by your imagination. For example, if you want to automatically rename classes, you can do that. If you want to automatically sort or group rules by their selector, you can do that. If you want to automatically detect and remove unused rules (combined with html parsing), you can do that! You can do that!


It turns out that our example code didn’t cover all the cases. You homework is to run it against the CSS file that’s bundled with Bootstrap, figure out what’s broken, and fix it. Good luck!

This article was originally posted at