The Art & Science of Folding CSS Code

One of the joys of working with CSS is that you can basically write the code any way you want. Sure there are some basic rules you have to follow (like using brackets), but for the most part you can format your CSS code as elaborately or as plainly as you see fit. You can use this vast flexibility to improve the organization and usability of your working stylehseets before compressing them for production use.

Regular Show

It’s common to see CSS that looks like this:

selector-01 {
	background-color: #333;
	border: 3px solid #EEE;
	color: #CCC;
}
selector-02 {
	clear: both;
	float: left;
	width: 50px;
}
selector-03 {
	padding: 10px;
	margin: 10px;
	z-index: 99;
}

..and the CSS file will just go on and on for miles like that, with everything on its own line, all properties tabbed once, and everything else lined up against the left side of the stylesheet, sort of like chain links or railroad tracks. This type of CSS formatting is practical and requires minimal thought to accomplish. The downside is that you get these incredibly long stylesheets that require way too much scrolling.

Five Times Less Scrolling

So then you get CSS Gurus like Chris Coyier who make things as efficient and concise as possible with single-line format:

selector-01 { background-color: #333; border: 3px solid #EEE; color: #CCC; }
selector-02 { clear: both; float: left; width: 50px; }
selector-03 { padding: 10px; margin: 10px; z-index: 99; }

That’s 3 lines of code compared to 15, so way more efficient. Single-line format also gets you some benefits like smaller file sizes and better performance. Heck, remove the white spaces and you’ve got a nicely optimized stylesheet. It’s a solid format, but with some downsides, like when you have many single-line declarations without any visual breaks, white space or comments to help navigate the document. It’s one thing to deliver a compressed/optimized stylesheet to the browser, but when you’re actually working with the CSS code, it’s advantageous to have plenty of visual texture to the document.

Adding Visual Texture

The most common and arguably easiest way of creating a visually textured stylesheet is to throw in some comments:

/* == HEADER == */
#header { background: url(images/header-bg.jpg) repeat-x; }
#header .inside { height: 136px; }
#header h1 { margin: 0; }
#header h1 a { display: block; width: 466px; height: 145px; text-indent: -9999px; position: absolute; top: 0px; left: -18px; background: url(images/logo.png) no-repeat; }
.description { position: absolute; left: 455px; top: 51px; color: #dfe0e1; }

/* == CONTENT == */
#main-content { width: 650px; float: left; clear: none; margin: -35px 0 0 0; }
.post { background: rgba(255,255,255,0.1); padding: 15px; position: relative; margin: 0 0 10px 0; }
body.single .post { margin: 0 0 25px 0; }
.post-inside { border: 1px solid white; background: url(images/post-footer.png) repeat-x bottom left; padding-bottom: 16px; }

/* == DETAILS == */
.meta { background: #143855; color: white; border-top: 1px solid white; padding: 3px 15px; }
.entry { background: white; padding: 15px; }
.entry h3 { padding: 5px 0; margin: 30px 0 15px 0; border-top: 1px solid #ccc; border-bottom: 1px solid #ccc; }

Even just a blank line in between the different groups of declarations is going to make reading and editing much easier. But even this level of formatting has its drawbacks, especially for longer documents with a comment for every few lines of code, soon the comments become indistinguishable. On their own, comments also fail to help when applied to large groups of declarations, as seen here with the CSS used to style the Comments area at DigWP.com:

/* == COMMENTS == */
#all-comments { padding: 15px; background: rgba(255,255,255,0.1); }
#comments { color: white; text-align: center; }
ol.commentlist { list-style: none; }
ol.commentlist li.comment { border-bottom: 1px dotted #666; padding: 15px; position: relative; }
ol.commentlist li.byuser { /* replaced with next line because we now have many registered users */ }
ol.commentlist li.comment-author-jeffstarr, ol.commentlist li.comment-author-chriscoyier { background: #bae7ff !important; }
ol.commentlist li.featured:after { content: url(images/star.png); position: absolute; top: 11px; left: -11px; }
ol.commentlist li.comment div.vcard cite.fn { font-style: normal; }
ol.commentlist li.comment img.avatar { float:right; margin: 0 0 10px 10px; }
ol.commentlist li.comment div.comment-meta { font-size: 10px; }
ol.commentlist li.comment div.comment-meta a { color: #ccc; }
ol.commentlist li.comment div.reply { font-size: 11px; }
ol.commentlist li.comment div.reply a { font-weight: bold; }
ol.commentlist li.comment ul.children { list-style: none; margin: 10px 0 0; }
ol.commentlist li.comment ul.children li.depth-2 { border-left: 5px solid #555; }
ol.commentlist li.comment ul.children li.depth-3 { border-left: 5px solid #999; }
ol.commentlist li.comment ul.children li.depth-4 { border-left: 5px solid #bbb; }
ol.commentlist li.comment ul.children li.depth-5 { }
ol.commentlist li.comment ul.children li.odd { }
ol.commentlist li.even { background: #fff; }
ol.commentlist li.odd { background: #f6f6f6; }
.comment-intro { margin: 0 0 10px 0; }
.diw_comment-author { color: #19517C; border-bottom: 1px solid #84A3BB; }
.comment-number { font-weight: bold; color: #19517C; }

Sure, you can get a good idea of what’s happening by examining the selectors, but it’s still like reading one of those old 500-page books with tiny type and no images. Books have come a long way, and so has the art of CSS code-folding.

CSS Code Folding

The basic idea behind folding CSS code is to take advantage of its extremely flexible syntax. Manipulating the presentation of code enables designers to bring rich visual context to their stylesheets. Expanding, branching, and folding CSS in logical, useful ways improves the usability of the code itself.

Code-folding is more of an art than a science..

Sure it’s not always necessary to format your stylesheets beyond the ordinary, but for web designers that spend a lot of time working with CSS, folding code is a way of life, with each author’s style as unique as the code itself. Code-folding is more of an art than a science, with some designers avoiding it completely and others taking it to the extreme with some seriously well-organized and tasty-looking CSS.

Micro Examples

Discussing the ideas and philosophy of folding code plunges into the deep abstract pretty quickly, so perhaps the best way to explore the concept is to consider a few simple examples of CSS-folding in action. Say we’re beginning a new design, and our stylesheet begins to look familiar using typical CSS formatting:

html {
	background-color: #b5b5ab;
	margin: 0;
	padding: 0;
	}
body {
	background: transparent url(images/bg1.png) repeat 0 0;
	color: #4c4c42;
	font: 16px/1.4 'Lucida Grande', Helvetica, Arial, sans-serif;
	margin: 0;
	padding: 0 0 5px 0;
	}
#wrap {
	background-color: #969688;
	margin: 0 auto;
	padding: 0;
	position: relative;
	width: 960px;
	}

This level of code-folding is sufficient for many situations, but becomes tedious and painful when you’re dealing with hundreds of declarations. So we could jump to other end of the “folding spectrum” and compress everything into single-line format:

html { background-color: #b5b5ab; margin: 0; padding: 0; }
body { background: transparent url(images/bg1.png) repeat 0 0; color: #4c4c42; font: 16px/1.4 'Lucida Grande', Helvetica, Arial, sans-serif; margin: 0; padding: 0 0 5px 0; }
#wrap { background-color: #969688; margin: 0 auto; padding: 0; position: relative; width: 960px; }

This takes our example from 19 lines of code down to four, but usability goes downhill as more rules and properties are added to the mix. Fortunately, the flexible syntax of CSS enables us to fold the code in useful, practical ways. Here is an example that’s sort of a mid-spectrum example of code-folding:

html {
	background-color: #b5b5ab;
	margin: 0; padding: 0;
	}
body {
	background: transparent url(images/bg1.png) repeat 0 0;
	font: 16px/1.4 'Lucida Grande', Helvetica, Arial, sans-serif;
	margin: 0; padding: 0 0 5px 0; color: #4c4c42;
	}
#wrap {
	background-color: #969688;
	margin: 0 auto; padding: 0; width: 960px;
	position: relative;
	}

..which may be folded even further, manipulating other aspects of the code, such as indentation, and placement of selectors and brackets:

html { background-color: #b5b5ab; margin: 0; padding: 0; }
body {
	background: transparent url(images/bg1.png) repeat 0 0;
	font: 16px/1.4 'Lucida Grande', Helvetica, Arial, sans-serif;
	margin: 0; padding: 0 0 5px 0; color: #4c4c42;
	}
	#wrap {
		background-color: #969688; position: relative;
		margin: 0 auto; padding: 0; width: 960px;
		}

By manipulating syntax and combining similar properties on the same line, we better consolidate the CSS without mashing it all up into long lines of code. For example, margin, padding, and width affect the box model in similar ways, so it makes sense to combine them on their own line. And there are many examples of this, where similar properties happen to fit beautifully on their own line. Consider the following declaration block:

#content {
	margin: 50px 0 0 15px;
	border: 1px solid #E7E9F6;
	-webkit-border-radius: 10px;
	-khtml-border-radius: 10px;
	-moz-border-radius: 10px;
	border-radius: 10px;
	background: #eee;
	width: 600px;
	float: left;
	clear: none;
	}

Yes that works fine, but for the CSS connoisseur, it’s like smacking your head into a telephone pole. It’s just so dumb-looking that you can’t help but die a little on the inside. But if you look at the different properties in that block, you’ll see several groups that consolidate quite naturally:

#content {
	margin: 50px 0 0 15px; padding: 0;
	background-color: #eee; color: #333;
	float: left; clear: none; width: 600px;
	border: 1px solid #E7E9F6;
		-webkit-border-radius: 10px;
		-khtml-border-radius: 10px;
		-moz-border-radius: 10px;
	border-radius: 10px;
	}

Here the CSS is folded by combining the following properties:

  • margin and padding
  • background-color and color
  • float, clear, and width

Plus we’ve improved visual context by tab-indenting the collection of browser-specific properties, -webkit-border-radius, -khtml-border-radius, and -moz-border-radius. Combining these three properties into a single line would increase efficiency, but arguably at the expense of usability. But that’s the beauty of CSS and code-folding: it’s ultimately up to the individual to decide how to best format their code.

Macro Examples

Zooming out a bit on the stylesheet, we see code-folding working on a higher level, with CSS that reads more like meta-poetry than lines of code. This happens as the cumulative result of folding and formatting different groups of selectors into meta patterns throughout the stylesheet.

Most of this so-called macro-folding is the result of creative tabbing and strategic line breaks. Consider the following code taken from my custom WordPress login tutorial, presented here in typical CSS format:

/* == AJAX LOGIN FORM == */
.username, .password, .login_fields {
	margin: 7px 0 0 0;
	overflow: hidden;
	width: 100%;
	}
.username label, .password label {
	float: left;
	clear: none;
	width: 80px;
	}
.username input, .password input {
	font: 12px/1.5 "Lucida Grande", "Lucida Sans Unicode", Verdana, sans-serif;
	float: left;
	clear: none;
	width: 200px;
	padding: 2px 3px;
	color: #777;
	}
.rememberme {
	overflow: hidden;
	width: 100%;
	margin-bottom: 7px;
	}
#rememberme {
	float: left;
	clear: none;
	margin: 4px 4px -4px 0;
	}
.wp-submit {
	margin: 5px 0;
	padding: 1px 3px;
	}
.userinfo {
	float: left;
	clear: none;
	width: 75%;
	margin-bottom: 10px;
	}
.userinfo p {
	margin-left: 10px;
	}
.usericon {
	float: left;
	clear: none;
	width: 15%;
	margin: 0 0 10px 22px;
	}
.usericon img {
	border: 1px solid #F4950E;
	padding: 1px;
	}
.userinfo .usersonline {
	float: right;
	clear: both;
	font-size: 12px;
	margin-right: 5px;
	}
.usersonline strong {
	font-weight: normal;
	}
.tab_container_login p {
	margin: 0 0 15px 0;
	padding: 0;
	}
.tab_container_login h3 {
	margin: 0 0 5px 0;
	color: #F4950E;
	padding: 0;
	}

Sorry for the long scroll, but that’s what you get when writing your code in this boring vanilla format. This CSS code is for a simple login/register form, and would be a relatively small part of any complete stylesheet. The elaborate comment placed before the entire section of code may help, but quickly proves futile as longer sections of code extend beyond the visible screen.

As discussed, the extreme way of handling this is to squish everything onto single lines. That’s gonna give us something that looks like a highly compressed stylesheet:

.username,.password,.login_fields{overflow:hidden;width:100%;margin:7px 0 0;}
.username label,.password label{float:left;clear:none;width:80px;}
.username input,.password input{font:12px/1.5 "Lucida Grande", "Lucida Sans Unicode", Verdana, sans-serif;float:left;clear:none;width:200px;color:#777;padding:2px 3px;}
.rememberme{overflow:hidden;width:100%;margin-bottom:7px;}
#rememberme{float:left;clear:none;margin:4px 4px -4px 0;}
.wp-submit{margin:5px 0;padding:1px 3px;}
.userinfo{float:left;clear:none;width:75%;margin-bottom:10px;}
.userinfo p{margin-left:10px;}
.usericon{float:left;clear:none;width:15%;margin:0 0 10px 22px;}
.usericon img{border:1px solid #F4950E;padding:1px;}
.userinfo .usersonline{float:right;clear:both;font-size:12px;margin-right:5px;}
.usersonline strong{font-weight:normal;}
.tab_container_login p{margin:0 0 15px;padding:0;}
.tab_container_login h3{color:#F4950E;margin:0 0 5px;padding:0;} 

Amazingly concise, but we can unfold, indent, and break our way to more descriptive, usable CSS code:

/* == AJAX LOGIN FORM == */
.username, .password, .login_fields {
	margin: 7px 0 0 0; width: 100%; overflow: hidden;
	}
	.username label, .password label { float: left; clear: none; width: 80px; }
	.username input, .password input {
		font: 12px/1.5 "Lucida Grande", "Lucida Sans Unicode", Verdana, sans-serif;
		float: left; clear: none; width: 200px; padding: 2px 3px; color: #777;
		}
		.rememberme { overflow: hidden; width: 100%; margin-bottom: 7px; }
		#rememberme { float: left; clear: none; margin: 4px 4px -4px 0; }
		.wp-submit { margin: 5px 0; padding: 1px 3px; }

	.userinfo { float: left; clear: none; width: 75%; margin-bottom: 10px; }
	.userinfo p { margin-left: 10px; }

	.usericon { float: left; clear: none; width: 15%; margin: 0 0 10px 22px; }
	.usericon img { border: 1px solid #F4950E; padding: 1px; }

	.userinfo .usersonline {
		float: right; clear: both; margin-right: 5px;
		font-size: 12px;
		}
		.usersonline strong { font-weight: normal; }

	.tab_container_login p {
		margin: 0 0 15px 0; padding: 0;
		}
	.tab_container_login h3 {
		margin: 0 0 5px 0; padding: 0;
		color: #F4950E;
		}

This set of rules now fits easily on the screen, with selector arrangement emulating its corresponding HTML markup. Repetitive groups of properties are consolidated into single lines, with commonly customized properties like font-size and color easily recognized. Finally, strategic use of line breaks and bracket placement further organize the different rules into distinct sub-sections.

As you begin folding the code in your stylesheets, you’ll notice patterns emerging from the uniquely formatted chunks of code. For example, the anchor styles may all be single-line format, heading styles might be heavily styled, and complicated markup may appear as more highly branched and folded.

So you get a sense of where you’re at in the stylesheet just by scrolling through the macro-folded code. Then as you zoom in, the micro-formatting provides additional context as you edit specific properties and selectors.

Endless Journey

There are endless ways to fold code, especially CSS. It’s more of an art-form than a science, and at its best happens naturally, as the designer applies their experience and skills to the creation of a beautiful, well-defined stylesheet.