CSS Architectures: Principles of Code Cleanup

This entry is part 1 of 5 in the series CSS Architectures

CSS Architectures

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.

CSS Architectures

CSS Architectures: New Best Practices >>

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • http://wassup2day.com Vaibhav

    A really helpful post man. I was always bad with creating web page designs and i had to learn from various sources. I must say yours is a nice post.

    • http://denisejacobs.com Denise Jacobs

      @Vaibhav – Glad you enjoyed the post. This is just the first half of the information, so keep an eye out for the second half of it!

  • DaveMaxwell

    Overall a good article, and I look forward to seeing the rest of the series. The only item here I hesitate to agree with is the Up the Efficiency for Speed example.

    #sidebar has way too large of a chance as being not the same as div#wrapper div#maincontent div#sidebar. The specificities are way too far off.

    #sidebar applies to ANY element with an id of sidebar. Could be a div, could be a ul, etc.

    div#wrapper div#maincontent div#sidebar applies only to the div with an id of sidebar which sits inside the div with an id of maincontent which sits inside the div with the id of wrapper.

    Will they select the same element? Probably. But this could be applied to a specific case, and not all the elements which may have an id of sidebar.

    #wrapper #maincontent #sidebar would be closer – still a risk of picking something else, but much less likely.

    • http://denisejacobs.com Denise Jacobs

      @DaveMaxwell – From my understanding, #sidebar would only be used on a page once by the nature of it being an #id. If it were a .class, then that style ruleset would be set up to be used on multiple elements on a given page. Generally speaking, one would create #sidebar as a set of styles to be used on a particular element, not on a lot of them as a .class would. Let me know if I totally misunderstand what you are saying.

      • DaveMaxwell

        That’s true – however, the example you provided isn’t quite that simple.

        The type of example you provided is often used to highlight the current menu item (basically a you are here).

        So you could have
        div#wrapper div#maincontent div#sidebar { background-color: red; color: #fff; }
        div#adminwrapper div#maincontent div#sidebar { background-color: grey; color: #000; }

        so if you have html like this: Text

        Text would be white letters on a red background.

        then on another page, if you have html like this: Text

        Text would be black letters on a gray background.

        All I’m saying is to be careful as it’s not necessarily a 1:1 change over, and to be sure you understand your page content before you start ripping selectors out. The example you provided MAY be correct and have the effect you want, but make sure it’s not a special case before doing so….

      • Zymara

        #sidebar may only be used once per page, but 2 different pages could have 2 different sidebars, one as div#sidebar and one as p#sidebar (for example). If both pages use the same stylesheet, obviously you need the element qualifier in addition to the ID to declare the styles for both.

        I’ve also had to work with crazy CMS implementations where IDs were duplicated in the same page, again requiring additional selector prefixes to target the correct element.

        So in general, yes, what you propose IS a best practice to strive for, while being aware that here are times when you just can’t.

      • Ari

        Denise is right, there should be only one instance of an ID selector — e.g., #sidebar — per web page. However, as @Zymara has pointed out, a stylesheet may be used by more than one web page making it necessary to include qualifiers.

        BTW, Great series Denise!

  • VF

    Can you fool the text editor to think x- is a change of syntax and thereby changing the colour for the entire line like a comment does?

    • http://denisejacobs.com Denise Jacobs

      @VF – I don’t know if you can, but it is worth trying! Let us know if you have any success with that.

  • McBenny

    Nice article!
    About the order of declarations in a CSS rule, I do not agree on the alphabetical order.
    Sure it helps find a declaration, but that’s the only point.
    When I write a rule, most of the time I think in “box-model mode”: I first consider the display mode of the element, then its outside parameters, then its boundaries before the inside of the element, and finally what to apply to the contained elements text etc.).
    If I write in alphabetical mode, I will go back and forth to respect my way of thinking.
    My solution is to order the declarations the way I think:
    .myBlock {display:block; float:left; margin:10px; border:1px solid #red; width:300px; height:150px; background:#green; padding:1em; text-align:center; line-height:1.2em; font-family:sans-serif; color:purple; cursor:help;}
    This way, as I know the order the elements, I can find them easily (just as easily as if the were in alphabetical order, really), I can write my rule in just a shot, and when I come back on the rule, I immediatly see the behavour of my element.
    But that’s just a way to do it.

    • AP.

      My thoughts exactly.

      • http://denisejacobs.com Denise Jacobs

        @McBenny and @AP – The alphabetical order is merely a suggestion. I know that one tends to hit a lot of nerves with people. One of the things I do myself is to do alpha for CSS 2.1 styles, and then list all CSS3 styles in the order of browser testing and then fallback (usually webkit-, moz-, o-, ms-, standard).

        Of course, it is really up to personal preference, but the most important thing is when working in a team. If you have a lot of people working the CSS, then it’s important to have everyone agree on the format that you are going to use and then have everyone go along with it. It’s annoying to be looking at someone else’s code and have to decipher their own little special way of arranging the style declarations.

  • inan

    Thank you, this is a useful and valuable post. It helps beginners or amateurs or say any developer to learn new things easily. Hope it continues.

    • http://denisejacobs.com Denise Jacobs

      @inan – There’s a second post coming, so be sure to watch for it. Also, there are more articles coming in the “CSS Architectures” series.

  • Dave

    Thanks Denise – some very useful tips in this.

    • http://denisejacobs.com Denise Jacobs

      @Dave – You’re welcome, Dave. There’s more where that came from, so keep watching for the sequel articles!

  • http://designfuturistic.com devender

    if i will talk of myself i usually forgot such thing to include in my style. Very helpful and it reminds us importance of clean and maintained coding.

    • http://denisejacobs.com Denise Jacobs

      @devender – Yes, clean code is very important :). Glad the article gave you some good reminders.

  • Christian

    I came up with the “X” trick on my own and was told by employers to just comment the line out.

    And here’s a little more I like to use when constructing styles:

    http://developer.cmzmedia.com/?p=9 (the more styles you have the more helpful this is)

    And indenting your HTML code yourself while you are coding it truly is a huge help. A lot of people don’t bother and then expect Firebug to do the work for them. Well, if you do it properly yourself you’re going to understand the relationships the various elements have to each other much better.

    • http://denisejacobs.com Denise Jacobs

      @Christian – Heh, you’re employer just may not know what is good for them. I guess they are happy paying you the extra time it takes to make the comments, right? :D

      And yes, I am a HUGE fan of indenting my HTML code – it makes all of the difference in the world to me, as I am very visual and find the patterns things more easily with visual help.

      • simmu

        I work with large to mid scale web application. I would not allow my front-end developer to use x over comment. Using x is just a quick dirty hack to comment out the style (For quick test is acceptable). I not sure if there is any implication on performance by assigning invalid attribute vs comment, def should look in to it. The reason I in favor of comment are:
        1. Easier for other user (backend and front-end developer) to read.
        2. When you optimize your stylesheet, removing comment is easier then removing x. (not that you can’t but most compressor understand comment syntax).

  • http://www.stickytoffee.co.uk Dennis

    Very good article, although I like the idea of alphabetical order, I tend to use a similar method to McBenny only I work in the order of Display, Inside, Outside.

    DaveMaxwell – #sidebar as an id should only appear in one element type once in any document, a class, however, may appear in different elements more than once in a document. If you work on that rule you shouldn’t create any conflicts.

    • http://denisejacobs.com Denise Jacobs

      @Dennis – Glad you liked the article! (and thanks for weighing in on the comments for me :D). See my response to @McBenny and @AP below. Definitely all about personal preference, but must agree on one approach within a team.

  • MB

    There is a such a push to use tools such as LESS to write CSS…but from what I’ve seen so far, using CSS pre-compilers tends to violate many of the basic rules you are mentioning. Thoughts on how to retain good coding practices when using LESS or other pre-compilers?

    • http://denisejacobs.com Denise Jacobs

      @MB, while I like the idea of pre-compilers, I haven’t really used any of them. I know that there are a lot of great articles on how to use pre-compilers like SASS and LESS with approaches like OOCSS and SMACSS.

      I have talked to several hard-core front-end devs who say that they still prefer good old fashioned, straight up CSS over the compilers. So, as with everything, it is a matter of choice.

  • Sai Pc

    Ok i agree with most of your points,but i dont know why so many ppl are suggesting this ‘x-’ thing..seriously guys,it is easier to type two slashes // rather than going to the extremes of the keyboard to find the x and -…i always use // to comment it out..and i think it is much easier.

    • http://denisejacobs.com Denise Jacobs

      @Sai Pc – as with everything, it’s all about personal preference. I’m just sharing what I have used and what worked for me. I tended to stay away from the // because I didn’t want to mix JavaScript practices with my CSS practices.

      But really, I say, whatever technique works for you (and your team — if you are not the only one touching the code) is the best.

  • http://www.nagella.us Nagella

    I am new to CSS , after reading this article i am so happy , this article is very nicely articulated , i love this. CSS alphabetical order and box model all these are new to me , i used to write whatever i like at that time. Thanks a lot Jacobs , please let us know if any new article is going to come. Appreciates your patient , responded to every one.

  • Gabe

    Nice article, though I would not agree for putting unnecessary comments on the header, e.g. author, creation date, etc., which most of the time end up cluttering the file with outdated information. That’s the responsibility of any version control system, which I’ll expect any professional project will use.

  • http://bfuturedigital.net Susan

    This is extremely helpful, as I am cleaning up an old site and was wondering about the performance of my past code specifically with long chains of selectors. I’ll be simplifying those.

    You mention a few online tools to get help in formatting, but I am wondering if there are recommendations for plugins or tools for IDEs that are being used ? ( At the most popular ones, Sublime Text 2, Coda, Espresso and a few others etc..)

    Thank you Denise!