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
andpadding
background-color
andcolor
float
,clear
, andwidth
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.
28 responses to “The Art & Science of Folding CSS Code”
Hi Jeff,
I am using Pagelines for my theme and I was able to play around a little bit with the CSS.
I changed the font in my header which was too small at the time. I believe that instead of using px it was em.
While an interesting way to format and organize your code, I think a more practical way is to maintain a development CSS file (organized and formatted however you like) and minimize your production CSS file.
This give you the best of both worlds: a formatted dev stylesheet that only you will see and a minified stylesheet that compresses everything into a single line.
It’s not always practical, but something to keep in mind.
Absolutely. I mention this idea in the opening and closing sections of the article.
In my website development I’ve been using my own custom .php file that creates two CSS files; stylesheet.css and optimized-stylesheet.css.
stylesheet.css contains all standard formatting (easily read) whereas the optimized-stylesheet.css file has all tabs, spaces and new lines removed [this file has all the CSS data on one line and is very difficult to read].
One is for development and the other for production.
Hope this helps others with ideas to streamline their CSS development.
Personally I would add two more rules to make that spot on:
“All properties that affect the box model go FIRST.”
“All properties with browser extensions go LAST”
That way you know all your -moz / -o / -webkit shite is out of the way and the more critical layout stuff is easily found at the start.
BOOM
Jeff,
Thanks, a great variety of styles, it’s always interesting to see inside the minds of others and how they tick.
For the record, I’m back on the multi-line style of listing each property/value on a unique line. There is just too much CSS3 stuff with all the vendor-prefixes that single line is getting too impractical, although I do miss the easy selector browsing sometimes.
I wonder if a better name could be come up with for your new style. “code folding” is that that thing they call where you collapse blocks of code in text editors so you don’t have to view that particular section right now. TextMate does it in CSS like this: http://cl.ly/8qxe
I agree about vendor-prefixed properties on their own line, but we can enjoy the best of both worlds by folding other code blocks any way that works best.
I’m totally open to calling it something else, such as formatting code, manipulating code, or whatever. But I do think that “code folding” describes it best. That text-editor functionality is more like “code collapsing” than folding, imo.
In most programming languages it’s simply called formatting. Like Jeff says, code-folding / code-collapsing is something you find in editors.
I actually came here to read about a code-editing / highlight system that included said folding… :-S
(Still a good article!)
Ha! I was about to leave a comment about how after I saw Chris Coyier’s css layouts in one of his tutorials a while ago he was not using multi-line and I wondered why he did that?
Now all I develop is wordpress websites and I never use multi-line mainly because of what Jeff pointed out about too much scrolling. You know those WP sites can end up having hundreds of lines of code.
So @Chris, it has been noted that you are back to multi-line but I am still following your old way!
Nice article Jeff!
Nice article. Thanks. Ditto what Jonathon said, Im always interested in how other people format their files. I will definitely be able to use some of these ideas in my own files. In addition to commenting my style sheets into sections – header, navigation, type, etc. – I also alphabetize within those sections whenever possible. Sometimes specificity doesn’t allow for it, but about 85-90% of the time it does.
Apart from the nested selectors this is how i’ve always coded my CSS it just make it simpler to read and if your consistant with how you “fold” it saves you so much time.
For me a common declaration would look like;
selector {
display; position; top; right; bottom; left;
width; height; margin; padding;
border; radius; background;
color; font; text;
}
I also follow this same rule when writing single line CSS i’m still on the fence as to which is better :)
I understand what you’re saying about the spacing and single-line being more “compact” but it’s (in practice) erroneous to say:
“Single-line format also gets you some benefits like smaller file sizes and better performance. ”
The difference is often less than negligible and you really should serve the sheets via gziping – which will blow away any advantage *at all*.
I personally prefer all our CSS to be mutlilined to better fit into source control.
My biggest problem with single line rules is you are then having to scan the line to find declarations which can have no common indentation – people have to remember the ordering if they want any sort of consistency.
I find people worrying over the Kb size of a spreadsheet – enough to argue removing a few indents & newlines seem to be overstating the “problem” – especially the minute you include a single photo or background on a page!
Each to their own I guess ? unless in a team environment.
I’m with Chris on ‘code folding’. That’s what hooked me in first place–I’m a Coda user and would LOVE to see the option to show/hide blocks of code. ;-)
That said, I’ve become an avid user of LESS for writing CSS. The nesting/indention is part of the syntax. Define it once (mixins.less) and call it as required–if for no other reason than to stop having to type all those vendor prefixes every time you need a box-shadow.
Tired of scrolling long CSS files (even w/LESS) I’ve been using P.erkins LESS framework (http://p.erkins.com/). The take-away there is that you set up short .less files (reset, grid, typography, mixins, etc.) and call them with @import in your style.less file. This shortens scroll time within primary style sheet considerably.
wow.. hadn’t seen less before.. great idea.. now if only someone will make us a nice firebug extension :)
thanks
Have you tried using a PHP file to replace your CSS file? It has many advantages and extremely flexible.
Just rename style-001.css to style-001.php and start with:
<?php
header(“Content-type: text/css;charset:UTF-8″);
/* comments that are not shown in CSS */
// another comment
$cx1=’f00′;
$cx6=’ff0′;
$bg1=”background-color:#” .$cx1 .”;color:#” .$cx6;
?>
<?php /* more comments not shown in CSS */ ?>
body {<?php echo $bg1′?>}
<?php /* have fun and start experimenting */ ?>
Indeed an interesting idea, as you with php (or perl for that matter) are able to remove stuff like whitespace before sending it to the user. But how does it preform in comparison to a normal css-file? The PHP will after all have to be processed by the server before sending it, as opposed to just sending the requested css-file.
Personally I prefer to fold my code like the first example in this article, for readability. I don’t see scrolling as a problem, I would rather scroll through a huge document and easily see what I’m looking for that having to stare into sea of letters to find it.
As a tradeoff it seems quite simple to use a “css-minifyer” before uploading if you want the css documents to be small in size for performance.
As mentioned “advantages and extremely flexible”.
The way I use it is to have two versions; one easy to read and the other squished. The latter shrinks to about 3K and I include this between <<style> tags.
By doing this I eliminate the file load link and the page load is just over one second.
http://tools.pingdom.com/?url=http://johns-jokes.com
Good article. One of the things I enjoy most about using Compass/SASS is nesting CSS declarations. It gives me a clear connection to the markup itself. I would not have thought to format plain CSS to match. Thanks!
Wow, your thoughts looks so similar to my ideas :) See:
— My presentation “CSS Management”
http://pepelsbey.net/pres/css-management/?full#TreeLike
Ttree view, last bracket indent, +sorting
CSS Comb — http://csscomb.com/: sorting tool for properties, based on groups from Zen Coding documentation
http://code.google.com/p/zen-coding/wiki/ZenCSSPropertiesEn