xtfer

Sorting the CSS Mess

Posted in Web Design by xtfer on February 18, 2009

You’ve just updated a website design or finished a lengthy series of design iterations, and your CSS file has grown with every move, but chances are you don’t need half the selectors that are in there. This can be especially true if you have adapted a default theme, or are using a templating system that has inheritance, like that used by Drupal.

Using the combination of a good CSS Optimizer, DustMeSelectors, and a little bit of PHP, however, you can fix it in no time at all.

Optimize your CSS

Running your CSS through an optimizer is good practice. It will reduce file size, sort selectors, remove incorrect properties and generally tidy your mess. There are several available on the interwebs, but my favourite is Optimizer over at Flyspray.

Some good settings for the Floele@Flyspray CSS Optimizer are:

  • Compression: High (puts each selector on its own line)
  • Sort both selectors and properties
  • Choose lowercase selectors and properties (always make your selectors lowercase)
  • Remove last ;

This should spit out a nice, clean CSS file sorted by ID’s, classes and elements, and then alphabetically.  Once you get used to this, it makes finding your selectors a piece of cake, and ensures that the CSS specificity is uniform.

If you didn’t write your CSS like this in the first place, you may find that your site has now changed(?!), so you may need to go back and correctly weight or remove selectors (I usually find myself able to remove properties after ordering my CSS, rather than adding them).

Dust off 

Next, you want to know which selectors you don’t actually need. Thankfully, there is a Firefox extension which makes this dead easy, Dust-Me Selectors

Once you have installed Dust-Me, simply visit each type of page on your site and click the Dust-Me icon to scan your css. I usually visit some combination of:

  • The home page
  • One of every content type
  • Administration pages
  • Channel or aggregation pages
  • Forums
  • Log in page
  • Any other special or unique page

At the end, you should be able to export a list of unused selectors to CSV from Dust-Me.

Cross Check

Here’s the annoying bit. Now, using the CSV list of selectors, cross-check this line-by-line with your original CSS file and remove anything that appears in both.

That’s what I started doing, but by line 10 of 256 I was over it, and decided it would be quicker to use PHP. So, here is the solution.

The code below will cross check your Optimized CSS file with a text file of Selector names to remove. 

There are some caveats with this script:

  • It assumes you have optimized first, to remove errors.
  • Selectors and their properties must be on a single line e.g.
  •  .style{width:100%;height:20px)
    not
    .style {
       width:100%;
       height:20px;
    }
  •  There are no comments in your files
  • The selectors to remove (from Dust-Me) are in a simple list inside a text file, with a new selector on each line, e.g.
  • .style
    .style a
    .style h2 

Save the script in a new file called process.php, save your css into the same folder in a file called style.css, and your list of selectors to selectors.txt.

Hit process.php in your browser, and it should spit out a list of the remaining selectors, which you can copy back over your original stylesheet (but save a backup of the original as well).

You may want to run this list back through the Optimizer to remove duplicate properties and make it a bit smaller again.

<?php
/**
 * Compares a css file with a list of selectors and removes matching
 * Files must be in this directory
*/

process();

function process() {
	// Get CSS file (style.css) and read into a starter array
	$css_original = "style.css";
	$style_setup = file($css_original,FILE_SKIP_EMPTY_LINES);

	// Transfer that into a key, value array
	$styles = array();

	foreach($style_setup as $line) {
		//pull the definition off the end
		$kv = explode("{",$line);
		$selectors = $kv[0];
		$definition = "{".$kv[1];

		//break up the selectors
		$s = explode(",", $selectors);

		//add the selectors and definitions to the styles array
		foreach ($s as $item){
			$key = trim($item);
			$styles[$key] = $definition;
		}
	}
	// remove duplicates
	$styles = array_unique($styles);

	echo "Style.css completed\n";
	echo '<h1>Original Styles</h1>';
	print_styles($styles);

	// Get Selectors list (selectors.txt) and read into a single column array
	$css_remove = "selectors.txt";
	$selectorslist = file($css_remove,FILE_SKIP_EMPTY_LINES);

	//remove dupes and trim whitespace
	$selectorslist = array_unique($selectorslist);
	foreach($selectorslist as $item) {
		$discardlist[] = trim($item);
	}

	// Find matches in both files and create a keep and discard array
	$css_discard = array();
	$css_keep = array();\

	foreach($styles as $key => $value){
		if(in_array($key,$discardlist)){
			$css_discard[$key] = $value;
		} else {
			$css_keep[$key] = $value;
		}
	}

	// print remaining style to screen
	echo '<h1>Remaining CSS</h1>';
	print_styles($css_keep);

}

function print_styles($items) {
	foreach($items as $key => $value){
		echo $key.' '.$value.'<br />';
	}
}
?>

This is a simple script, and intended for a specific purpose, so you may find it doesn’t work in some situations – I haven’t tested it extensively. I also am not responsible if you accidentally delete CSS you really needed… you need to make those calls yourself. Best of luck.

Tagged with: ,

Leave a Reply