Be a CSS Team Player: CSS Best Practices for Team-Based Development

Emily P. Lewis | May 5, 2010

 

How many times have you picked up a project that someone else started, only to discover that the creator's original code is a mess? Or you work with several team members, each of whom has their own way writing code? Or you revisit a project you created years ago, and you don't remember what you were thinking?

It happens to me all the time. In fact, I recently spent almost 300 hours fixing a vendor's facepalm-inducing CSS. Those 300 hours were filled with frustration for not only myself, but other members of my team. And it stole valuable time and resources that would've been better spent on new development.

If that vendor had simply followed some basic guidelines in his CSS, precious time and money would've been saved for my employer, not to mention my own sanity would be in a much better state. In this article, you will learn best practices for writing CSS to help you avoid inconsistency and redundancy; in effect, setting standards that streamline team-based development.

Get Organized!

Good organization is the foundation of well-written CSS. It helps me — and whoever has to update the code in the future — understand and scan the CSS and more quickly jump to specific styles.

Before I even start writing styles, I first define the organization of my CSS document according the different content "sections" of the web page I'm styling. More often than not, these sections are the same across different web sites:

  • Header
  • Navigation
  • Main content
  • Sidebar
  • Footer

So, within my CSS file, I add comments indicating where the styles for each of these sections will go:

/*---GLOBAL---*/
/*---HEADER---*/
/*---NAV---*/
/*---CONTENT---*/
/*---SIDEBAR---*/
/*---FOOTER---*/

Note that the very first organizational comment I added is GLOBAL. This section doesn't correspond to any specific content on my site, but instead serves to indicate where I'll maintain what I refer to as "global" styles. These are generic styles, not specific to any site content, such as those for layout/structure, typographic elements — headings, paragraphs, lists and links — <form>s and <table>s.

By keeping these global, generic styles at the top of my CSS file, it helps me take advantage of the cascade. All CSS following these style declarations will properly inherit attributes, and I can more easily override attributes when needed.

More CSS, More Organization

I work with very large web sites that rely on tons of CSS. When dealing with so many lines of styles, I like to add a secondary level of comments within each section. In GLOBAL, for example, I indicate the types of styles I'll maintain:

/*---GLOBAL---*/
    /*--Structure--*/
    /*--Typographic--*/
    /*--Forms--*/
    /*--Tables--*/
/*---HEADER---*/
/*---NAV---*/
    /*--Primary--*/       
    /*--Secondary--*/  
    /*---CONTENT---*/  
/*---SIDEBAR---*/  
/*---FOOTER---*/

And you can also see that I added secondary-level comments to NAV, indicating where styles for the primary and secondary navigation will exist.

This might be overkill for your purposes. In fact, for smaller sites with less CSS, I don't typically use the secondary-level comments. But this additional detail on large CSS files has proven very useful for my team.

Format Freedom

The format you should use for these organizational comments is ultimately up to you. What you see in the example above is simply me and my team's preferred method. Some people like to have their organizational comments appear on two lines:

/*   HEADER      
------------------------------*/

Some people use a special character, like an equal sign, as a flag to aid searching within a text editor:

/*   =Header      
------------------------------*/

Some people don't use secondary-level comments. And some folks use an entirely different organizational structure that doesn't divide the CSS according to page content, but instead by element types: headers, images, lists, etc. The key is to define your preferred format and be consistent using it.

Want to organize according to content elements? No problem. If you want lowercase comments, go for it. Don't want to indent secondary-level comments? Don't. Don't like hyphens and want to use periods? Go nuts. Just do what makes the most sense for you and your team.

Comment for Communication

We've taken a look at using comments for organization, but you should also use comments for communicating to the other members of your team or even your future self.

What, Who, When

When working as part of a team, it is particularly useful to communicate amongst members what a given CSS file is for, who authored it and when it was last updated. On my team, we add a "summary" comment to the top of our CSS files that provides these details:

/*----TITLE: Main screen styles | AUTHOR: EPL | UPDATED: 03/23/10 by EPL----*/

The title information is useful when working with multiple stylesheets, such as one for screen, one for print, one for mobile and even those for IE hacks. The author information allows all team members to know who to go to if there are questions about the original CSS, while the updated information lets the team know when the last update occurred and who made it.

As for your summary comment, include only what is useful to your team. If you don't need author information, skip it. If you want a copyright statement, add it. I've even seen summary comments that include address and contact information:

/*---- IE6 screen styles (ie6.css)  Company ABC 1234 Avenue of the Americas New York, NY 10020 https://companyabc.com  Updated: 03/23/10 by EPL ----*/

Color Key

One of the most helpful uses of CSS comments I've encountered is a color key, where the color palette for the web site is defined:

/*---COLORS: Green #b3d88c | Blue #0075b2 | Light Gray #eee | Dark Gray #9b9e9e | Orange #f26522 | Teal #00a99d | Yellow #fbc112---*/

A color key is particularly useful during the development phase, saving you time from sampling colors or looking them up from some style guide. Need to know the hex value for blue links? Scroll to the key, copy and paste.

On my team, we maintain the color key at the top of our CSS documents, just after the summary comment and immediately before all of the style declarations and accompanying organizational comments. We also try to keep the key simple to keep maintenance simple, but it is up to you how complex you want to make it.

The format, too, is your call. You can keep all the color definitions grouped on a single line, as in the example above, or split them out across multiple lines:

/*---COLORS      
Green #b3d88c      
Blue #0075b2      
Light Gray #eee      
Dark Gray #9b9e9e      
Orange #f26522      
Teal #00a99d      
Yellow #fbc112 
---*/

Once again, the goal is to find the format that works best for your needs and be consistent once you've defined that format.

Development & Debugging

There are times when I've been in the middle of development and had to hand off my CSS to another team member. And there are times when I'm banging my head against a wall trying to figure out why IE is borking on my CSS, and I just need to walk away. Comments are essential for these situations.

Making a note to yourself or your fellow team members, indicating what a style is and, perhaps, that it isn't complete saves time and headaches:

/*--//--Styling for link states is pending new changes from designer, please don't edit | EPL 03/23/10--\\--*/ 
a, a:link, a:visited {    
    color:#0075b2;     
    text-decoration:none;
}  

a:hover, a:focus, a:active {    
    color:#b3d88c;
}

I typically format these types of comments differently than my other comments in order to make them stand out more. And I make them as long and detailed as needed. Again, use what works for you.

Keep in mind, though, once you are finished with your development/debugging, it is a good idea to get rid of these types of comments. If they are no longer relevant to the work, they are no longer relevant in the CSS. And they just bloat your files.

Resets

CSS resets have become pretty popular. They are styles added to the top of CSS files that set HTML elements to a baseline value in order to avoid presentational inconsistencies — margin, padding, line-height, etc. — across browsers:

/*---RESET---*/ 
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td {    
    margin: 0;    
    padding: 0;    
    border: 0;    
    outline: 0;    
    font-weight: inherit;    
    font-style: inherit;    
    font-size: 100%;    
    font-family: inherit;    
    vertical-align: baseline; 
}

The above example is an excerpt from Eric Meyer's Reset Reloaded, which I use often. But I tend to edit his reset to not include any markup elements that I don't use, and I recommend you do the same. For example, the sites my team builds almost never use the <kbd>element, nor <iframe>, <applet> or a handful of other elements included above.

So, I remove those element selectors. It makes a negligible difference in page load times or bandwidth, but I feel it helps avoid confusion amongst team members by not referencing markup that isn't used.

I also make edits to the reset styles if I don't want to override browsers' built-in styles, such as how unordered lists are treated. In these cases, I make sure those elements are not included in the style declaration.

I should clarify, though, that CSS resets aren't for everyone. There are plenty of reasons to not use them. I say decide for yourself and, if you do go the reset route, make your reset styles as clean and specific to your site as possible.

Semantic Naming Conventions

One of the most frustrating things about working with someone else's CSS is when the naming conventions for classor id values make no sense whatsoever. Imagine encountering the following:

.f23 {    
    background: #fff;    
    border: 1px solid #ff0;    
    font-weight: bold;    
    padding: 10px; 
}

I have absolutely no idea what .f23means. And even worse, if there are no organizational comments, I don't know what content .f23 is referencing. Is it in the header? The main content? Navigation?

In these situations, particularly with a large site, it is possible to waste ridiculous amounts of time trying to track down where this class value is referenced in the markup. If the author had instead used semantic naming conventions — those with meaning, those based on the content being styled — I would have context for the CSS:

.alert {    
    background: #fff;    
    border: 1px solid #ff0;    
    font-weight: bold;    
    padding: 10px;
}

As you can see, .alert offers a lot more context for the CSS than a random letter-number combination.

But more than just context, semantic naming conventions are useful for saving time. Consider a company who goes through frequent branding changes. If you developed the CSS using presentational rather than semantic class and id values, you are looking at far more CSS — and maybe even markup — maintenance than is necessary.

For example, what if you assigned class="blueBox" to a call-out box on the site that uses the company's blue color palette. And then the company rebrands and they now have a red-based palette. blueBox means nothing at this point. So, not only do you have to update the hex value for that style in your CSS, but you may have to change all references in your markup.

If you had instead used class="callOut" (or something equally meaningful), you could have far less work on your hands.

Class Crazy

With CSS, I tend to agree with the "less is more" school of thought. Just because you can assign a class to every element, doesn't mean you should.

During my 300 hours of fixing that vendor's shoddy CSS, I found an overabundance of classes that didn't need to be there. For example, every <label> element was assigned class="label" and every <form> had class="form". But our design and markup only had one style for <form> element, which contained only one style for <label> element.

form.form {    
    float: right;    
    margin: 0;    
    padding: 5px; 
} 

label.label {    
    clear: both;    
    float: left;    
    text-align: right;    
    width: 145px;
}

While the resulting CSS wasn't, itself, too terrible (redundant, but not terrible) it caused confusion. As the designer who inherited the CSS, I saw the .form class and assumed that there must be some other <form> styles defined by a different class value. And the hunt for those non-existent styles was just a waste of my time.

Classitis != Specificity

And that is just a simple example. A more detailed example of class craziness I encountered seems to result from a desire for specificity:

<div id="feature" class="tabs">    
    <ul class="tabs">       
        <li class="tabs"><a href="#newServices">New Services</a></li>     
        <li class="tabs"><a href="#newProducts">New Products</a></li>    
    </ul> 
</div>

Notice how class="tabs" is applied to every element in the above markup? This resulted in the following CSS to target the list elements:

div.tabs ul.tabs li.tabs {    
    float: left;    
    font-weight: bold;    
    padding: 3px; 
}

A much cleaner, lighter solution for targeting the <li>s would be:

#feature li {    
    float: left;    
    font-weight: bold;    
    padding: 3px;
}

If you don't need a classvalue to target your elements for styling, don't use them. They, too, add weight to your markup and CSS, and they significantly reduce scannability within the CSS.

You should also note that I referenced only the id value as the selector in the last example: #feature rather than div#feature. Adding div to the selector is only necessary if you need it for specificity. If you don't, it just adds more to your CSS; more that you and your teammates have to scan through. Also, by using the least specific declaration you can, it helps if you later need to override any style.

Multiple Classes

After that last bit, you may be getting the impression that I don't like lots of classes. While I definitely don't encourage the use of unnecessary, redundant classes, I am a huge fan of keeping my CSS lean by using multiple classes to style elements that have presentation in common, but may need some differentiation:

.announcement {    
    background: #eee;    
    border: 1px solid #007b52;
    color: #007b52;    
    font-weight: bold;    
    padding: 10px;
}  

.newsAnnouncement {    
    background: #eee;    
    border: 1px solid #007b52;
    color: #007b52;    
    float: right;    
    font-weight: bold;    
    padding: 10px; 
}

These two declarations are identical, except .newsAnnouncement is floated right. Rather than repeat all of the shared style information, I could instead have:

.announcement {    
    background: #eee;    
    border: 1px solid #007b52;
    color: #007b52;    
    font-weight: bold;    
    padding: 10px;
}  

.floatR {    
    float:right; 
}

And then, in my markup, assign both classes to the content for news announcements:

<div class="announcement floatR">

But wait! Didn't I just talk about semantic naming conventions rather than presentational? I sure did. But there are always exceptions to every rule.

Yes, .floatR is presentational. But it works for this situation and it is generic enough that it could be used for other situations needing multiple classes, so this is an approach my team uses often.

Grouped Selectors

Another problem I dealt with in my 300-hour torture session was identical style declarations sprinkled across multiple stylesheets. The only difference between the declarations, was that each was applied to a different selector:

#productFeature {    
    background: #fff;    
    border: 1px solid #00752b;    
    float: left;    
    padding: 10px; 
}  

#contactFeature {    
    background: #fff;    
    border: 1px solid #00752b;    
    float: left;    
    padding: 10px; 
}

#serviceFeature {    
    background: #fff;    
    border: 1px solid #00752b;    
    float: left;    
    padding: 10px; 
}

This not only bloated the already-massive CSS files, but made maintenance a nightmare. The solution is to combine those selectors to reference the single style declaration:

#productFeature, #contactFeature, #serviceFeature {    
    background: #fff;    
    border: 1px solid #00752b;    
    float: left;    
    padding: 10px; 
}

Now, if the style needs to be updated, only one declaration needs to be updated, rather than three.

One-Line or Multi-Line?

All of the CSS examples in this article are written using a multi-line format, where each property-value pair appears on its own line. This is a widely-used convention not only within CSS files, but in books and articles about CSS. Most people feel it is more readable, which is why I used it in this article.

However, for the work I do with my team — especially with large CSS files — I write my styles on one line:

.alert {background: #fff; border: 1px solid #ff0; font-weight: bold; padding: 10px;}

Personally, I feel this is more readable. And my team members agree. When dealing with so many lines of CSS, the multi-line approach becomes cumbersome to scan through. Keeping everything on one line seems to make it easier.

For you and your team, focus on consistency. Pick what format is most comfortable for your team, and use it each and every time.

To Alphabetize or Not?

Some people recommend alphabetizing your style properties within each declaration, so that you can more quickly and easily find a property. This isn't something I've been particular about in the past, but after dealing with that vendor's mess of CSS, I can appreciate that some thought applied to organization within style declarations is a good idea.

What I find more useful than alphabetical order, though, is to organize properties according to context. For example, I like to keep all box properties together. Or if I'm using absolute positioning, I keep those values grouped:

#logo {    
    border: 1px solid #000;    
    margin: 0;    
    padding: 0;    
    position: absolute;    
    top: 5px;    
    right: 3px; 
}

Yet again, there is no right or wrong here. Just decide on a property order and be consistent using it. 

Make Shorthand Your Friend

Using CSS shorthand has long been heralded as a method for keeping your CSS light and lean. But it also helps tremendously within teams, not only by aiding scannability, but by setting the standard syntax that everyone should follow. This reduces the time team members spend thinking about and writing CSS.

Zero Values

If you are specifying a value of zero, it isn't necessary to specify pixels (or ems or percentages …):

margin: 2px 3px 0px 4px

becomes

margin: 2px 3px 0 4px

Hex Colors

Hexadecimal colors consisting of three pairs of digits can be reduced by removing one digit from each pair:

color: #ff0000

becomes

color: #f00

Box Properties

Box properties like margin, padding and border can be combined if the values are the same for each of the four sides:

padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px

becomes

padding: 5px

Also, with box properties, if your top and bottom or left and right property values are the same, you only need to declare two:

padding: 5px 10px 5px 10px

becomes

padding: 5px 10px

Font Properties

Font properties can be combined:

font-style:italic; font-weight:bold; font-size: 90%; font-family: Arial, Helvetica, sans-serif;

becomes

font: italic bold 90% Arial, Helvetica sans-serif

Background Properties

Background properties, too, are great to combine:

background-color:#fff; background-image: url(logo.png); background-repeat: no-repeat; background-position: 0 10%;

becomes

background: #f00 url(logo.png) no-repeat 0 10%

Please note: for the last two shorthand examples, font and background properties, the order you declare property values matters. Be sure to reference the W3C specification.

Validate, Validate, Validate

While some folks think it is a good rule–of–thumb to validate your CSS, I think it is an absolute requirement. Validation gives you a chance to make sure your work is ready to share with other members of your team, along with:

  • Easier development and troubleshooting
  • Browser consistency, both now and in the future
  • Faster page loads
  • Part of due diligence for accessibility
  • Write it right = write it once

I recommend using the W3C CSS Validation Service.

Compression Tools

If you and your team have concerns about file size, page loads and bandwidth (who doesn't), then you should consider a compression tool for your CSS. These tools can do everything from shortening your hex color values to removing comments. Here are a few worth considering:

I do not recommend utilizing compression on staging or development files, because while compression reduces file size, it also reduces your and your team's ability to scan and work with the CSS. All the comments are gone. All white space is gone. You no longer have a CSS file that easy to work with. Leave compression as the last step for live/production files.

Tip of the Iceberg

What I've covered in this article is just a handful of basic practices to help keep you and your CSS team happy and working efficiently. There are dozens more guidelines you can follow to further make your CSS the best it can be. If your curiosity is piqued, I recommend you continue reading:

Follow the Golden Rule

Whether you work on an internal team, with vendors and sub-contractors or by yourself as a team of one, these CSS practices will help establish the ground rules for being a good CSS team player, saving both time and frustration.

Just hearken back to your pre-school days and remember the Golden Rule: do unto your CSS as you would have others do unto it.

 

About the Author

Emily Lewis is a freelance web designer of the standardista variety, which means she gets geeky about things like semantic markup andCSS, usability and accessibility. As part of her ongoing quest to spread the good word about standards, she writes about web design on her blog, A Blog Not Limited, and is the author of Microformats Made Simple and a contributing author for the HTML5 Cookbook. She’s also a guest writer for Web Standards Sherpa.net magazine and MIX Online.

In addition to loving all things web, Emily is passionate about community building and knowledge sharing. She co-founded and co-manages Webuquerque, the New Mexico Adobe User Group for Web Professionals, and is a co-host of the The ExpressionEngine Podcast. Emily also speaks at conferences and events all over the country, including SXSW, MIX, In Control, Voices That Matter, New Mexico Technology Council, InterLab and the University of New Mexico.

Find Emily on: