All too often, the CSS for major (and minor) websites is a textbook case of code bloat and redundancy, with lines of code that boast unnecessary use of qualifier elements, overly specific selectors from unnecessarily long selector chains, overdependence on descendent selectors when other selectors would be more appropriate, and the inappropriate or unnecessary use of !important. We can all institute several basic, solid CSS writing practices to vastly improve the maintainability of any organization’s stylesheets. Ultimately, however, what we should really shoot for is structuring a given site’s stylesheets to dramatically increase scalability.
Our approach, then, is two-fold. First, we must put in place several essential practices for writing clean and efficient CSS. Second, we need to learn about and institute the central methodologies of the increasingly popular scalable CSS architectures to take our sites’ stylesheets to another level.
I’ll explore both of these topics throughout this and my following article, but before we get into making code scalable, let’s do a bit of CSS cleanup, starting with some of my favorite tricks.
A Few Helpful Techniques
Learning workflow tricks from other developers is often really helpful. Here are a few of my personal favorites.
Targeting Styles
It’s a good idea to have a method for targeting the styles on your page. If you aren’t using a tool like the Internet Explorer Developer Toolbar, Mozilla’s Firebug or Chrome Developer Tools, this old-school method of adding the property outline can help you see and work with the element that you desire more quickly:
.searchform > .searchsubmit {
width: 14%;
height: 25px;
background: transparent url(images/icon_magnify.png) 0 0 no-repeat;
outline: 1px solid red
}
The rationale behind using this property and values is that outline does not add to the dimensions of the element like border does. Even the use of red (or any other color name) is significant. When coding, use only hexadecimal, rgb(a) or hsl(a) color codes. Then you know that when you see a color name, it’s there solely for the purpose of troubleshooting. Be aware that outline is not supported by IE8 and lower.
Adding Test Styles
Another good practice when testing and troubleshooting is to indent the new trial styles.
.searchform > .searchsubmit {
width: 14%;
height: 25px;
background: transparent url(images/icon_magnify.png) 0 0 no-repeat;
margin: -2px 0 0 0;
}
With the indentation, you know for sure that the style is temporary, and it’s easy to scan and find later. When you decide that the style should stay, indent it as you would the rest of the permanent styles.
Disabling Styles
With a good way to add new styles, here’s a way to quickly disable them : “X” them out by placing an x- in front of either the style selector or the style rule:
.social a {
-moz-transition: opacity 0.3s ease 0s;
x-display: block;
height: 35px;
opacity: 0.4;
}
This method is quicker than commenting out the style. It’s also easy to scan and find, and you have the style in place if you decide later that you want to keep it.
CSS Cleanup and Optimization Guidelines
Now that we’ve got those tricks out of the way, let’s turn our focus to some rules of thumb for writing clean, optimized code—or for when you’re cleaning up someone else’s CSS spaghetti. We’ll go from the macro to the micro level, first exploring how to improve the readability and semantics of the HTML, and then moving on to ways to better organize and cut down on the number of style declarations.
Macro-Optimize
It’s easy to get focused on the style declarations themselves, but before you create selectors, you have to make the HTML and the stylesheets themselves reader-friendly.
Provide Stylesheet Information and Indicate Structure
With really large stylesheets, I’m a fan of using a table of contents. For developers new to a given stylesheet, knowing what the sections are or which names to jump to when they need to find a group of styles is incredibly helpful.
At the basic level, I recommend inserting the developer’s information (name and so on) and the last updated date in the stylesheet. This way, if any questions come up about what’s in the document, the current developer knows who to ask.
/* stylesheet information for XyZ Corp
File created date: 09.15.2010
Last modified date: 06.04.2012
By: [name]
*/
Also, I recommend putting in a preliminary table of contents so that other developers have an idea of the structure of the document and the different sections for styles.
/* Table of Contents
- Link Styles
- Other sitewide styles
- Actions
- Layout
- LOGO
- TOP NAV
- NAVBAR
- SUBNAV
*/
…
(later in the document…)
/* =Layout */ (etc.)
Note that including the equals sign (=) before the section name of the stylesheet is deliberate—it acts as a flag and a way to search through the document more easily.
Annotate and Nest
Annotating and nesting markup helps you keep track of the beginning and end of elements that contain other elements, and this enables you to identify the pieces faster.
Annotate divs and other major layout elements that begin with <!-- #id or .class name -->
by using the markup <!-- /end #id or .class name -->
or <!-- / #id or .class name -->
.
Nesting may seem like an unnecessary step, but it’s useful from a visual perspective and, by clearly indicating visual levels, also makes it easier to find problems like block-level elements inside inline elements, as well as the improper closing and reopening of elements, which can create major layout issues—culprits that validation often doesn’t help you find that easily.
You can see the difference in the following example:
Before
<body>
<div id="pagewrap">
<div id="header">
<h1>Website Title</h1>
<ul id="navigation">
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
<div id="contentwrap">
<div id="maincontent">
<h2>Main Content Title</h2>
<p>Main content, which is so much more important than the secondary content that it makes one teary with emotion.</p>
</div>
<div id="secondarycontent">
<h3>Sidebar Title</h3>
<p>Sidebar content, which is not as important as the primary content (which is why it is in the sidebar)</p>
</div>
<div id="footer">
<p>standard copyright and footer information</p>
</div>
</body>
After
<body>
<div id="pagewrap">
<div id="header">
<h1>Website Title</h1>
<ul id="navigation">
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul><!-- end #header -->
<div>
<div id="contentwrap">
<div id="maincontent">
<h2>Main Content Title</h2>
<p>Main content, which is so much more important than the secondary content that it makes one teary with emotion.</p>
</div><!-- end #maincontent -->
<div id="secondarycontent">
<h3>Sidebar Title</h3>
<p>Sidebar content, which is not as important as the primary content (which is why it is in the sidebar)</p>
</div><!-- end #secondarycontent -->
</div><!-- end #contentwrap -->
<div id="footer">
<p>standard copyright and footer information</p>
</div><!-- end #footer -->
</div><!-- end #pagewrap -->
</body>
You can find more information and tips for organizing your stylesheets in “Creating Effective Semantic Markup.”
Micro-Optimize
Micro-optimization cuts down file size, speeds up page load time and encourages best practices. Here are some ways you can improve your CSS on a micro level.
Alphabetize the Rule Order
Putting your CSS declarations in alphabetical order is a great way to set the stage for clean code and fewer problems. Why? Because your style declarations will be that much easier to target and locate.
Example One:
.login {
margin-top: 5px;
line-height: 1.5em;
padding-left: 5px;
float: right;
list-style-type: none;
width: 80px;
font-weight: bold;
border-left: 1px solid #69824d;
}
Example Two:
.login {
border-left: 1px solid #69824d;
float: right;
font-weight: bold;
line-height: 1.5em;
list-style-type: none;
margin-top: 5px;
padding-left: 5px;
width: 80px;
}
Up the Efficiency for Speed
Long chains of elements for selectors force the browser to search unnecessarily through the page’s DOM to make a match. Eliminating element qualifiers and ditching descendent selectors in favor of more direct ones helps speed things up.
Preoptimization:
div#wrapper div#maincontent div#sidebar {
background: #fff url(bg.png) repeat-x 0 0;
border: 1px solid #ff0;
font: normal 1.33em/1.33 Georgia, serif;
margin: 10px 20px;
padding: .1em;
}
Postoptimization:
#sidebar {
background: #fff url(bg.png) repeat-x 0 0;
border: 1px solid #ff0;
font: normal 1.33em/1.33 Georgia, serif;
margin: 10px 20px;
padding: .1em;
}
Read more about this topic at “Optimizations for Improving Page Load Times.”
KISS: Keep It Simple and Short
Less is more when it comes to style declarations and selectors. For style declarations, follow these rules:
- Use shorthand properties whenever possible (and remember these items when using shorthand: the shorthand property syntax; property value order, if any; the default values and required property values)
- Condense values and units
- Avoid duplicate properties whenever possible
Before:
#sidebar {
background-color: #fff;
background-image: (bg.png);
background-position: 0 0;
background-repeat: repeat-x;
border-width: 1px;
border-style: solid;
border-color: #ffff00;
font-family: Georgia, serif;
font-size: 1.33em;
line-height: 1.33em;
font-weight: normal;
margin: 10px 20px 10px 20px;
padding: .1em;
}
After:
#sidebar {
background: #fff url(bg.png) repeat-x 0 0;
border: 1px solid #ff0;
font: normal 1.33em/1.33 Georgia, serif;
margin: 10px 20px;
padding: .1em;
}
Condense the Code
Finally, removing multiple lines and indenting also helps keep your site efficient and speedy. Using multiple lines, nesting and indenting are recommended while developing a CSS, but once a site is ready to go live, minifying the CSS is the best route. A couple of good tools that condense CSS are CSS Compressor and CSS Drive.
Tools Can Lend a Helping, Uh… Hand
Keeping these rules in mind while you’re coding helps prevent you from making gaffes that could cost you time and frustration later. But don’t think you have to do it all yourself, as some great tools are available that help with cleaning up your code. I think CleanCSS and Code Beautifier are worth checking out. Use these tools to clean up your code even further while you learn to integrate some of the approaches I’ve described.
Denise R. Jacobs is an author, speaker, web design consultant, and creativity evangelist. Based in Miami, Florida, she is the author of The CSS Detective Guide, and co-authored InterAct with Web Standards: A Holistic Approach to Web Design.