How to Micro-Optimize Your CSS

[] There are many ways to optimize your web pages. In addition to reducing HTTP requests and delivering compressed files, we can also minify code content. The easiest way to minify your CSS is to run it through an online code minifier, which automatically eliminates extraneous characters to reduce file size. Minification shrinks file size significantly, by as much as 30% or more (depending on input code). This size-reduction is the net result of numerous micro-optimization techniques applied to your stylesheet. By learning these techniques and integrating them into your coding practice, you’ll create better-optimized CSS during the development process. Sharper skills, cleaner code, faster downloads – it’s a “win-win” for everyone.

In this Perishable Press article, you’ll learn how to write leaner, cleaner CSS using 10+ micro-optimization techniques..

The basic idea behind micro-optimizing your CSS involves writing clean code, eliminating extraneous characters, and reducing overall file size. And you don’t have to rely on an automated script to do everything for you. Instead of writing lazy, sloppy, bloated code and then just dumping your hideous CSS into an automated minifier, it’s better to understand and practice as many micro-optimization tips as possible, given your particular coding style and specific project requirements.

I doubt that anyone is going to use all of the micro-optimization techniques presented in this article. If you did, your code would look like you ran it through a minifier, something like this:

#comments ol{margin:10px 0 20px 25px}
#comments ol li{margin:7px 0 7px 25px;width:90%}
#comments .comment ol,#comments .comment ul{margin:3px 0 10px 5px}
#comments .comment ol li,#comments .comment ul li{margin:5px 0 5px 25px}
#comments #comments-closed{margin:5px 0 15px 15px}
#comment-policy{margin:5px 10px 0 0;width:300px;float:right;clear:both}
#comment-policy span{font-family:Monaco,"Panic Sans","Lucida Console","Courier New",Courier,monospace,sans-serif}
#comment-form{padding-top:10px;margin-top:15px}
#comment-form fieldset{border:0 none}
#respond #comment-form p{margin:0 0 0 20px}
#comment-form div.input,#comment-form div.textarea{border:1px solid #CF7400;float:left;clear:both;margin:0 0 10px 20px}
#comment-form div.textarea{height:221px;width:470px}
#comment-form textarea{height:211px;width:460px}
#comment-form input,#comment-form textarea,#comment-form #submit{font-family:Verdana,Helvetica,Arial,sans-serif;border:1px solid #A6945E;background:#291F16;font-size:11px;color:#A6945E;padding:4px;margin:0}
#comment-form #submit{background:#3B2E22}
#comment-form input:focus,#comment-form input:active,#comment-form textarea:focus,#comment-form textarea:active,#comment-form #submit:hover,#comment-form #submit:focus,#comment-form #submit:active{border:1px solid #FFC;background:#3B2E22;color:#cc9}
#comment-form #comment-info{padding:0 0 15px}

That’s about as optimized as it gets, but you don’t want to work with code that looks like that. Fortunately, it’s not an “all-or-nothing” scenario. Think of micro-optimization as a hypothetical spectrum, with completely minified code at one end, and completely “un-minified” code at the other. As designers, we each place differently along the spectrum, with each person’s CSS reflecting their ability to write clean and well-optimized code. All of this of course is completely subjective – it’s up to you as a designer to develop your own coding strategy using as many (or as few) of these micro-optimization techniques as desired.

The goal of this article is to introduce you to the many different ways of micro-optimizing your stylesheets, enabling you to write leaner, cleaner CSS. While every technique is effective, not all of them are going to be practical during the development process. Use what works. Even if you ignore these techniques and just crank out your code through a minifier, this article will help you understand micro-optimization and how the process of minification works.

Tip #1: Use the shortest possible color values

For properties where color is used, use the shortest value possible. For example, let’s say you want a white background applied to the <article> element. You could write something like this:

article { background-color: rgb(255,255,255); }

That works, certainly, but we can do better:

article { background-color: #ffffff; }

That’s good, but we can use the shorthand format for certain color values:

article { background-color: #fff; }

Nice. But look at that background property – there is no need to write it all out like that. Instead, just use this:

article { background: #fff; }

So let’s compare the “before” and “after” for this example:

article { background-color: #ffffff; }
article { background: #fff; }

A significant improvement. Also note that certain color names are shorter than their hexadecimal representations. For example, writing “red” is more efficient than “#cc0000”.

Tip #2: Merge duplicate properties

After you have completed your stylesheet, take a moment to scan for duplicate properties and merge them. You could do this manually, or for longer stylesheets you can use an online CSS optimizer (404 link removed 2012/10/20) to automate the process. Either way, the goal is to reduce the amount of code used in your stylesheets by eliminating redundant properties, values, and declarations. As a simple example, let’s say you discover the following rulesets in different locations in your stylesheet:

p {
	font-family: Georgia, serif;
	font-weight: normal;
	line-height: 1.33em;
	font-size: 1.22em;
	}
	.
	.
	.
p {
	font-family: Georgia, serif;
	font-weight: normal;
	line-height: 1.33em;
	font-size: 1.33em;
	}

In this order, the latter rules will be applied and the first ignored, so you might as well combine the properties to save a few bytes:

p {
	font-family: Georgia, serif;
	font-weight: normal;
	line-height: 1.33em;
	font-size: 1.33em;
	}

Granted, duplicate properties are usually more subtle and complicated than this example, but the idea is clear: eliminate redundant properties by combining them into one. On the page, your design is going to look the same, but behind the scenes you’re delivering the stylesheet faster, using fewer resources.

Tip #3: Use shorthand syntax whenever possible

I bet some of you were virtually screaming during the previous example: “combine the properties using shorthand!!” And rightly so, but using CSS shorthand is important enough to warrant a tip all its own.

The idea with CSS shorthand syntax is that you can consolidate certain properties into a single declaration. Let’s return to the previous example:

p {
	font-family: Georgia, serif;
	font-weight: normal;
	line-height: 1.33em;
	font-size: 1.33em;
	}

That’s a lot of code, and if you’re writing everything out like that for other selectors as well, your stylesheet could quickly inflate with all sorts of bloat. Here is our ruleset after consolidating the declarations via shorthand:

p {
	font: normal 1.33em/1.33 Georgia, serif;
	}

Much, much better. There are actually quite a few properties that may be combined using shorthand syntax. Here are a few more examples:

/* these 4 properties */
background-color: #fff;
background-image: url(i/dope.png);
background-repeat: repeat-x;
background-position: 0 0;
 
/* can be written as */
background: #fff url(i/dope.png) repeat-x 0 0;

/* these 4 properties */
margin-top:    10px;
margin-right:  20px;
margin-bottom: 10px;
margin-left:   20px;

/* can be written as */
margin: 10px 20px 10px 20px;

/* these 3 properties */
border-width: 1px;
border-style: solid;
border-color: red;

/* can be written as */
border: 1px solid red;

Hopefully these are self-explanatory. If not, check out these fine articles. The goal here is to encourage you to use these shorthand rules.

Tip #4: Combine similar numerical values

Looking at the previous example, we see another case where micro-optimization is possible. Consider the following:

margin: 10px 20px 10px 20px;

For properties such as margin and padding that allow for multiple numerical values, we can save bytes by combining them:

margin: 10px 20px;

This rule is equivalent to the previous example, where 10px sets the margin for the top and bottom, and 20px sets it for the right and left. If all four sides were the same, we could simplify even further:

margin: 10px;

Keep an eye on this. There are numerous properties for which this shorthand may be applied. And it certainly helps shave off the weight.

Tip #5: Omit extraneous zeros

This one is subtle, but the savings can add up. When you write numerical values, do not include any extraneous zeros. For example:

padding: 0.1em;
margin: 10.0em;

You really don’t need those extra zeros, so wipe them out:

padding: .1em;
margin: 10em;

In the second line, we also killed the period, which is unnecessary for whole numbers. Remember, these are micro-optimization techniques, meant to provide cumulative savings on file-size, bandwidth, and server resources. Incremental changes produce an overall optimizing effect. Just sayin.

Tip #6: Omit units for zero-values

This is a no-brainer, but something that took me about a year to fully appreciate and embrace. Consider this:

padding: 0px;

Looks harmless enough, but there are two extra characters that don’t need to be there. When it comes to zero values, you don’t need to specify the unit. Zero somethings is still zero, nothing, nada. Just use zero and forget about it:

padding: 0;

Significant? Next time you’re digging around in your stylesheet, count up all the zero-values and multiple the total by two – that’s how many characters we are saving for each file load.

Tip #7: Omit the last semicolon

Did you know that the last semicolon in every ruleset can be omitted? It’s true, there is no need to include it. Let’s return to our paragraph example:

p {
	font-family: Georgia, serif;
	font-weight: normal;
	line-height: 1.33em;
	font-size: 1.33em;
	}

The last declaration block in any ruleset does not require the closing semicolon. So we can write this:

p {
	font-family: Georgia, serif;
	font-weight: normal;
	line-height: 1.33em;
	font-size: 1.33em
	}

..and then further optimize the code via shorthand notation:

p { font: normal 1.33em/1.33 Georgia, serif }

To me, it still looks weird not including the semicolon, and in fact, most of the designers I study do in fact include the last semicolon pretty much for every ruleset. Would love to hear your opinion on this.

Tip #8: Remove comments from production files

Yes, CSS comments are essential to maintaining a clean and well-organized stylesheet, but they are 100% useless to browsers. So why include them in your production files? To the browser, all of those carefully placed comments are literally completely ignored, even though they continue to consume valuable server resources, bandwidth, and download time. So get rid of ‘em!!!

If this sounds like blasphemy to you, relax. I explain how to enjoy the best of both worlds at the end of this article.

Tip #9: Remove unnecessary whitespace

Remove as much whitespace as possible. Except for a few shorthand cases, it’s simply not necessary and bloats your code by as much as 50% or more. Let’s look at an example. Here we have a typically styled body selector:

body {
	font-family: "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
	background-color: #333;
	text-align: center;
	margin: 0px auto;
	font-size: 62.5%;
	color: #FFF;
	}

Removing the needless whitespace, we get this:

body{font-family:"Trebuchet MS",Verdana,Arial,Helvetica,sans-serif;text-align:center;background:#333;margin:0px auto;font-size:62.5%;color:#fff}

13 spaces and 8 line breaks were removed from this ruleset. Seem pointless? Consider this: if we have 50 (a modest number) selectors in our stylesheet, each averaging 10 spaces, we have over 500 characters that can be removed. That’s over 500 bytes per file load, which is cumulatively significant for sites with any considerable amount of traffic.

Note that there are property values that must include whitespace in order to operate. Properties condensed into shorthand notation are a good example, as seen here:

p {
	font:normal 1.33em/1.33 Georgia,serif;
	}

See how the whitespace is used to differentiate between the different values? Whitespace can be removed from between the property-name and the first proerty-value, but it needs to be there between the values themsleves. Here is what it would look like if we removed all of the whitespace:

p {
	font:normal1.33em/1.33Georgia,serif;
	}

Obviously, this isn’t going to make any sense to the browser, and the rule will be ignored (although IE may do something with it).

And of course, all of this brings us to our next and final micro-optimization tip:

Tip #10: No code-folding shenaniganz!

If there is one thing I enjoy, it’s formatting my CSS with all sorts of elaborate folds, tabs, and spacing. I like to make it look pleasing to the eye. None of this efficient single-line stuff. Unfold it, tab it in, and make it look hot. Here is a hearty example of how I am folding and formatting my code these days:

hr {
	margin: 25px 0 25px 0;
	background: #CF7400;
	text-align: left;
	padding: 15px 0;
	display: block;
	border: 0 none;
	color: #CF7400;
	height: 1px;
	clear: both;
	width: 96%;
	}
acronym, abbr {
	border-bottom: 1px dotted #514031;
	cursor: help;
	}
ins { text-decoration: underline; }
del { text-decoration: line-through; }
sup {
	font-size: 10px;
	line-height: 0;
	color: #cccc99;
	}
em       { font-style: italic; }
small    { font-size: 10px;    }
strong   { font-weight: bold;  }
strong:target, h3:target, h4:target {
	background: #CF7400;
	padding-left: 25px;
	}
code, kbd, samp, tt, var {
	font-family: "Courier New", Courier, monospace, sans-serif;
	color: #cccc99; /* #cc9933 #cccc66 #cccc99 */
	font-size: 11px;
	}
	h3 code { font-size: 13px; }
pre {
	border-left: 1px solid #CF7400;
	padding: 10px 0 12px 10px;
	background: #3B2E22;
	overflow: auto;
	margin: 25px 0;
	width: 525px; /* 95% of 555px = 525px */
	}
	pre:hover {
		border-left: 1px solid #FFFFCC;
		background: #3B2E22;
		}

Just look at all that pointless folding and formatting! It’s a crying shame, as far as optimization goes. A far more efficient way of writing the same CSS looks like this:

hr { background:#CF7400;margin:25px 0;text-align:left;padding:15px 0;display:block;border:0 none;color:#CF7400;height:1px;clear:both;width:96%; }
acronym,abbr { border-bottom:1px dotted #514031;cursor:help; }
ins { text-decoration:underline; }
del { text-decoration:line-through; }
sup { font-size:10px;line-height:0;color:#cc9; }
em { font-style:italic; }
small { font-size:10px; }
strong { font-weight:bold; }
strong:target,h3:target,h4:target { background:#CF7400;padding-left:25px; }
code,kbd,samp,tt,var { font-family:"Courier New",Courier,monospace,sans-serif;color:#cc9;font-size:11px; }
h3 code { font-size:13px; }
pre { border-left:1px solid #CF7400;padding:10px 0 12px 10px;background:#3B2E22;overflow:auto;margin:25px 0;width:525px; }
pre:hover { border-left:1px solid #FFC;background:#3B2E22; }

See, no crazy folding shenaniganz. Pretty boring, but damn efficient. I first began using this technique after working with CSS-Guru Chris Coyier on the Digging into WordPress site. He writes everything in single-line format, so I gave it a shot – and liked it. There is a certain practical elegance to single-line CSS, and it involves much less scrolling, which is in itself a great way to optimize not just site performance, but your performance.

Bottom line: tabs and spaces consume bandwidth – design accordingly. A good way to go about it is to create two versions of your stylesheet: one for careful development and another optimized for production. More on this here.

Tip #11: Validate your CSS!

Once you get everything looking good, take a moment to run your stylesheet through an online CSS validator. It’s fast, free, informative, and is a great way to catch anything that you may have missed. I am always surprised to see some of the mistakes that I have made in my own stylesheets – some subtle, some blatantly obvious.

Bonus Tips: Other Ideas

A couple other ideas occurred to me while writing this post. First, one thing that most designers and CSS optimizers seem to miss is the blank space after selector names. For example, this:

a:link, a:visited {}

..could be written this way:

a:link,a:visited{}

Those extra spaces are useless to the browser, so feel free to remove them to save some a few more bytes.

The second thing that is pretty uncommon is removal of line breaks between rulesets. Consider the following code:

h1{color:#111}
h2{color:#333}
h3{color:#777}

About as optimized as is usually seen around the Web, but we can go even further by removing the line breaks after each ruleset:

h1{color:#111}h2{color:#333}h3{color:#777}

Almost ridiculous, this level of minification is probably best implemented after development. Otherwise you would be scrolling sideways along an seemingly endless string of code. If you can find (or configure) a minifier that will do this for you, it may further reduce file size.

It’s all about teh micro-optimization

Individually, each of these optimization tips may seem like small potatoes. But when you’re talking about 10, 20, or more instances of each optimization technique in a single stylesheet, it adds up in a hurry. Then multiply the savings of a single file by the total number of times it will be delivered. Doing the math, you’re going to see that these “micro-optimization” techniques are extremely beneficial in terms of download speed, bandwidth savings, and server resources. It may be difficult to just suddenly start writing well-optimized code, but by gradually integrating some of these techniques into your own practice, eventually you’ll be producing some high-octane, well-optimized CSS.

The bottom line is that you should be optimizing your production stylesheets. There are always cases where you want to leave the code formatted and human-readable, but for 99% of production sites, you are better off delivering the most bandwidth-friendly files possible. Machines don’t care how pretty your code is – just ask Google about that.

The easy way to do all of this

Writing clean and well-organized stylesheets often goes against most of everything we’ve discussed here. But it doesn’t have to. Eventually, I would like to get to the point where I can write well-organized and well-optimized CSS the first time around, without needing to edit or change anything later. Imagine just being able to write a production-ready stylesheet in Notepad. Bam! You’re done.

Unfortunately, all of those comments, whitespaces, and semicolons help us to produce stylesheets that are clean, organized, and manageable. And that’s perfectly fine. Adopt as many micro-optimization techniques as you want, and then continue to write your code with as much fluff as needed to make it understandable and maintainable. Then, once you have your development stylesheet ready to go, run it through a good CSS optimizer to optimize it for the production environment. Just keep your elaborately formatted stylesheet as-is, and then crank out an optimized production version to use on the “live” site. It’s like getting the best of both worlds!