CSS - Best Practices
  1. Use HTML for struture and content. Use CSS for styling / layout. We should not be using old HTML tags such as b, u, i, font, center, and attributes such as align, and valign. These had been deprecated. Using these may cause browser to go into quirk mode, and display differently across the browser. Always validate your HTML. Validation also make the page load faster. As we fix bugs, or implement new features, we should check each page against IE6, IE7, IE8, Firefox 3. For Firefox, we can install HTML Validator.
  2. Stop using   as spacer.
  3. Always close your tag
  4. Use meaningful class names and IDs. If an ID or class name consist of multiple words, use underscore between words.
  5. Generic rule set should be dedicated to one thing. Use multiple classes in the HTML to achieve the desired combined effects
  6. Understand CSS. Keep our style sheets clean, and small.
  7. Use /* … */ inside style sheet to comment how each ruleset is used.
  8. Each ruleset (including selectors and { … }) can be either all in one line, or multi-lines. However we should not have to scroll right, and the overall readability of the entire file is not compromised.
  9. Combine elements: h1, h2, h3 { … } if these elements share the same ruleset
  10. Avoid using IDs and class names like "left", and "right". Imagine that in the future you may decide that you would rather see the box floated to the other side. You would have to return to your HTML and change the class name in order to adjust the presentation of the page. This is unsemantic. HTML is for markup and content. CSS is for presentation. If you must return to HTML to change the presentation (or styling) of the page, you are doing it wrong.
  11. Use CSS shorthands
  12. Avoid unnecessary selectors
  13. Allow block elements to fill their space naturally (avoid declaring the width of an element unless it is necessary)
  14. Absolute positioning is a handy aspect of CSS that allows you to define where exactly an element should be positioned on a page to the exact pixel. However, because of absolute positioning's disregard for other elements on the page, the layouts can get quite hairy if there are multiple absolutely positioned elements running around the layout.
  15. Link external style sheets in the 'head' tag.
  16. Put CSS in the document head. Specifying external stylesheets and inline style blocks in the body of an HTML document can negatively affect the browser's rendering performance. Browsers block rendering a web page until all external stylesheets have been downloaded. Inline style blocks (specified with the <style> tag) can cause reflows and shifting of content. Therefore, it's important to put references to external stylesheets, as well as inline style blocks, in the head of the page. By ensuring that stylesheets are downloaded and parsed first, you can allow the browser to progressively render the page. As required by the HTML 4.01 Specification (section 12.3), always put external stylesheets in the <head> section using the in the <link> tag. Don't use @import. Also make sure that you specify the stylesheets in the correct order with respect to scripts. Put <style> blocks in the <head> section.
  17. Use semantic HTML. Use h1 to h6 for heading. Use 'ul' for navigation.
  18. If a style is used to address an issue that is specific to a particular version of IE, put that rule in the file for that browser, and use conditional comment to load that style sheet.
  19. Use inline style (the style attribute) only when necessary. Ask yourself if this style is specific to this page. I find that the width property is almost always specific to the page, therefore should not be in main style sheet. We had problems when we change the width in CSS for one page, and it mess up other pages.
  20. Keep tag names in lowercase.
  21. Cut, cut, cut. This includes: markup, unused javascript code, unused CSS, etc.
  22. Be aware of properties that inherit from a parent element. Another way to avoid writing redundant code is to be aware of properties that inherit from a parent element to a child element or elements. There are quite a few inherited properties: color, font (and related properties), letter-spacing, line-height, list-style (and related properties), text-align, text-indent, text-transform, white-space, word-spacing. In certain older browsers, the inheritance feature can be buggy, but the modern browsers generally have no trouble with correct inheritance.
  23. Mozilla style system breaks rules up into four primary categories (ID Rules, Class Rules, Tag Rules, Universal Rules). The key selector is the last part of the selector (the part that matches the element being matched, rather than its ancestors). For example, in the rule 'a img, div > p, h1 + [title] {…}', the key selectors are img, p, and [title]. The first category (ID Rules) consists of those rules that have an ID selector as their key selector: treeitem > treerow > treecell#myCell:active {…}. If a rule has a class specified as its key selector, then it falls into the 'Class Rules' category: menuitem > .menu-left[checked="true"] {…}. If no class or ID is specified as the key selector, the next candidate is the tag category. If a rule has a tag specified as its key selector, then the rule falls into the 'Tag Rules' category: input[type="checkbox"] {…}. All other rules fall into the 'Universal Rules' category: tree > [collapsed="true"] {…}. The style system matches rules by starting with the key selector, then moving to the left (looking for any ancestors in the rule’s selector). As long as the selector’s subtree continues to check out, the style system continues moving to the left until it either matches the rule, or abandons because of a mismatch. The categories exist in order to filter out irrelevant rules (so the style system doesn’t waste time trying to match them). The fewer rules required to check for a given element, the faster style resolution will be. If an element has an ID, then only ID rules that match the element’s ID will be checked. Only Class Rules for a class found on the element will be checked. Only Tag Rules that match the tag will be checked. Universal Rules will always be checked.
  24. Avoid Universal Rules. Make sure a rule doesn’t end up in the universal category! Like any other category, the number of rules that we have for each category will impact how fast the browser can evaluate the rule. For other categories, the browser may have a hashing algorithm which allow evaluation to be faster, whereas that may not be the case for the 'Universal Rules' category. Also, due to the nature of the 'Universal Rules' category (browser not able to use getElementById(), getElementsByClassName(), getElementsTagName()), rules that fall into the 'Universal Rules' category are slow by nature.
  25. Don’t qualify ID Rules with tag names or classes. If a rule has an ID selector as its key selector, don’t add the tag name to the rule. Since IDs are unique, adding a tag name would slow down the matching process needlessly. Exception: When it’s desirable to change the class of an element dynamically in order to apply different styles in different situations.
  26. Use the most specific category possible. The single biggest cause of slowdown is too many rules in the Tag Category. By adding classes to our elements, we can further subdivide these rules into Class Categories, which eliminates time spent trying to match rules for a given tag.
  27. Avoid the descendant selector. The descendant selector is the most expensive selector in CSS. It is dreadfully expensive—especially if the selector is in the Tag or Universal Category. Frequently, what is really desired is the child selector. Using the descendant selector is banned in User Interface CSS without the explicit approval of your skin’s module owner. Descendant selectors are inefficient because, for each element that matches the key, the browser must also traverse up the DOM tree, evaluating every ancestor element until it finds a match or reaches the root element. The less specific the key, the greater the number of nodes that need to be evaluated.
  28. Tag Category rules should never contain a child selector. Avoid using the child selector with Tag Category rules. This will dramatically lengthen the match time (especially if the rule is likely to be matched) for all occurrences of that element.
  29. Question all usages of the child selector. Exercise caution when using the child selector. Avoid it if you can.
  30. Removing unused CSS is an important step in improving rendering performance.
  31. Optimizing the definitions of the rules. For pages that contain large numbers of elements and/or large numbers of CSS rules, optimizing the definitions of the rules themselves can enhance performance. The key to optimizing rules lies in defining rules that are as specific as possible and that avoid unnecessary redundancy, to allow the style engine to quickly find matches without spending time evaluating rules that don't apply.
  32. Avoid rules with child or adjacent selectors. Child and adjacent selectors are inefficient because, for each matching element, the browser has to evaluate another node. It becomes doubly expensive for each child selector in the rule. Again, the less specific the key, the greater the number of nodes that need to be evaluated. However, while inefficient, they are still preferable to descendant selectors in terms of performance.
  33. Avoid rules that apply the :hover pseudo-selector to non-link elements. The :hover pseudo-selector on non-anchor elements is known to make IE7 and IE8 slow in some cases*. When a strict doctype is not used, IE7 and IE8 will ignore :hover on any element other than anchors. When a strict doctype is used, :hover on non-anchors may cause performance degradation.
  34. Make your rules as specific as possible. Prefer class and ID selectors over tag selectors.
  35. Remove redundant qualifiers.
  36. Avoid using descendant selectors, especially those that specify redundant ancestors. For example, the rule body ul li a {…} specifies a redundant body selector, since all elements are descendants of the body tag.
  37. Specify image dimensions. Specifying a width and height for all images allows for faster rendering by eliminating the need for unnecessary reflows and repaints. When the browser lays out the page, it needs to be able to flow around replaceable elements such as images. It can begin to render a page even before images are downloaded, provided that it knows the dimensions to wrap non-replaceable elements around. If no dimensions are specified in the containing document, or if the dimensions specified don't match those of the actual images, the browser will require a reflow and repaint once the images are downloaded. To prevent reflows, specify the width and height of all images, either in the HTML <img> tag, or in CSS. Specify dimensions that match those of the images themselves. Don't use width and height specifications to scale images on the fly. If an image file is actually 60 x 60 pixels, don't set the dimensions to 30 x 30 in the HTML or CSS. If the image needs to be smaller, scale it in an image editor and set its dimensions to match (see Optimize images for details.) Be sure to specify dimensions on the image element or block-level parent. Be sure to set the dimensions on the <img> element itself, or a block-level parent. If the parent is not block-level, the dimensions will be ignored. Do not set dimensions on an ancestor that is not an immediate parent.
  38. Specify a character set early. Specifying a character set early for your HTML documents allows the browser to begin executing scripts immediately. HTML documents are sent over the Internet as a sequence of bytes accompanied by character encoding information. Character encoding information is specified in the HTTP response headers sent with the document, or in the HTML markup of the document itself. The browser uses the character encoding information to convert the stream of bytes into characters that it renders on-screen. Because a browser cannot correctly render a page without knowing how to construct the page's characters, most browsers buffer a certain number of bytes before executing any JavaScript or drawing the page, while they search for character set information in the input. (A notable exception is Internet Explorer versions 6, 7, and 8.) Browsers differ with the respect to the number of bytes buffered and the default encoding assumed if no character set is found. However, once they have buffered the requisite number of bytes and begun to render the page, if they encounter a character set specification that doesn't match their default, they need to reparse the input and redraw the page. Sometimes, they may even have to rerequest resources, if the mismatch affects the URLs of external resources. To avoid these delays, you should always specify the character encoding as early as possible. Prefer HTTP over meta tag parameters. There are several ways to specify the character set for an HTML document. You configure your web server to specify the charset parameter, with the correct character encoding, in the Content-Type header for all documents that are of type text/html; e.g. Content-Type: text/html; charset=UTF-8. You can also include the http-equiv="content" attribute in the meta tag in the HTML code, and specify the charset parameter; e.g. <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> . If possible, configure your web server to specify the character set in the HTTP headers. Some browsers (e.g. Firefox) use a shorter buffer delay before executing JavaScript if the charset is present in the header; that is, they can skip the additional buffering delay required to check the HTML markup.
  39. Always specify a content type. Before browsers can begin to check for a character set, they must first the determine the content type of the document being processed. If this is not specified in the HTTP header or the HTML meta tag, they will attempt to "sniff" the type, using various algorithms. This process can cause additional delays, besides representing a security vulnerability. For both performance and security reasons, you should always specify a content type for all resources (not only text/html).
  40. Be sure to specify the correct character encoding. It's important that the character set you specify in an HTTP header or HTML meta tag match the character encoding actually used to author your HTML documents. If you specify a charset parameter in both the HTTP header and HTML meta tag, make sure they match each other. If the browser detects an incorrect or mismatched encoding, it will render the page incorrectly and/or incur additional delays while it redraws the page. For more information on valid character sets, see Section 5.2, Character Encodings in the HTML 4.01 Specification.
  41. Use class selectors instead of descendant selectors.
  42. Be practical. So we know that ID’s are the most efficient selectors. If you wanted to make the most efficiently rendering page possible, you would literally give every single element on the page a unique ID, then apply styling with single ID selectors. That would be super fast, and also super ridiculous. It would probably be extremely non-semantic and extremely difficult to maintain. You don’t see this approach even on hardcore performance based sites. I think the lesson here is not to sacrifice semantics or maintainability for efficient CSS.
  43. Text-transform is a highly-useful CSS property that allows you to "standardize" how text is formatted on your site. For example, say you're wanting to create some headers that only have lowercase letters. Just add the text-transform property to the header style like so: text-transform: lowercase;
  44. Use a css framework
  45. Use css reset
  46. Use DOCTYPE and use the right DOCTYPE. The doctype declaration matters a whole lot on whether or not your markup and CSS will validate. In fact, the entire look and feel of your site can change greatly depending on the DOCTYPE that we use. Read more about DOCTYPE at A List Apart. Use XHTML 1.0 Transitional if you have no experience with doctypes. It requires you to use XHTML instead of HTML, and thus forces you to take a step towards standards-compliant markup. On the other hand it allows for more tags and attributes than its Strict brother, so it's easier to implement. <!DOCTYPE html PUBLIC "-W3CDTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">. See Web Page Development Best Practices
  47. Use CSS Optimizer and CSS Compressor to shrink CSS.
  48. Keep our style sheets clean, and small. Our current style sheet contains: font-family: Verdana, Arial, Helvetica, sans-serif; throughout the file. This is not necessary. We can define this rule for the body element, and all other elements inherit this rule. Keeping our style sheet small and clean, make it easier to maintain, and make the page load faster.
  49. Allow Block Elements to Fill Their Space Naturally. For block level element, we do not have to specify the width attribute.
  50. Keep structure and design separate
  51. Use progressive enhancement
  52. Do not make functioning of the website dependent on optional technology, such as CSS and client-side scripting: optional technology should complement the information on the site and its use, and should not interfere with access to it if this technology is not supported.
  53. The alt (alternative) attribute should be used on every img (image) and area element and should provide an effective alternative text. Do not use an alt attribute to display tooltips. Instead, use the title attribute.
  54. Use of the longdesc (long description) attribute is preferred if the alternative text on the alt attribute is inadequate for understanding the information in the image.
  55. When using image maps, indicate an effective alternative text for both the img element and each area element by means of the alt attribute.
  56. Decorative images should be inserted via CSS as much as possible. Informative images should be inserted via HTML.
  57. Applying CSS Image Replacement techniques for replacing essential information is not recommended.
  58. Use the label element to explicitly associate text with an input field in a form.
  59. Group input fields by means of the fieldset element.
  60. Do not use client-side script for essential functionality on web pages

Generic rule set should be dedicated to one thing. Use multiple classes in the HTML to achieve the desired combined effects.

For example, in CSS, we have:

.rounded_corner_top_left {
    border-top-left-radius: 6px;
    -moz-border-radius-topleft: 6px;
    -webkit-border-top-left-radius: 6px;
.rounded_corner_top_right {
    border-top-right-radius: 6px;
    -moz-border-radius-topright: 6px;
    -webkit-border-top-right-radius: 6px;

Then, in HTML, we have class="rounded_corner_top_left rounded_corner_top_right".

http://www.communitymx.com/content/article.cfm?cid=90F55 - Writing Efficient CSS
https://developer.mozilla.org/en/Writing_Efficient_CSS - Writing Efficient CSS for use in the Mozilla UI
http://developer.apple.com/internet/webcontent/bestwebdev.html - Web Page Development Best Practices
http://code.google.com/speed/page-speed/docs/rendering.html - Optimize browser rendering
http://css-tricks.com/efficiently-rendering-css/ - Efficiently Rendering CSS
http://www.useit.com/alertbox/9707a.html - Effective Use of Style Sheets
http://http//www.ormanclark.com - The Art and Zen of Writing CSS
http://www.threestyles.com/tutorials/css-shorthand-guide/ - CSS Shorthand – A Guide to Cleaner and Faster Coding
http://www.456bereastreet.com/archive/200502/efficient_css_with_shorthand_properties/ - Efficient CSS with shorthand properties
http://www.456bereastreet.com/archive/200610/useful_tips_for_writing_efficient_css/ - Useful tips for writing efficient CSS
http://net.tutsplus.com/tutorials/html-css-techniques/10-principles-of-the-css-masters/ - 10 Principles of CSS Master
http://webdesign.about.com/od/css/a/aa073106.htmhttp://www.456bereastreet.com/lab/web_development_mistakes/ - Web development mistakes
http://sixrevisions.com/css/12-common-css-mistakes-web-developers-make/ - 12 Common CSS Mistakes Web Developers Make
http://www.pxleyes.com/blog/2010/03/8-common-css-mistakes-and-how-to-fix-them/ - 8 Common CSS Mistakes and How to Fix Them
http://zoompf.com/blog/2009/12/browser-performance-issues-with-charsets/ - Browser Performance Issues with Charsets
http://www.kylescholz.com/blog/2010/01/performance_implications_of_charset.html - Performance Implications of "charset"
http://www.smashingmagazine.com/2010/06/07/the-principles-of-cross-browser-css-coding/ - The Principles Of Cross-Browser CSS Coding
http://webdesignledger.com/inspiration/subtle-details-taking-web-designs-to-another-level - Subtle Details: Taking Web Designs to Another Level
http://chriseppstein.github.com/blog/2009/09/20/why-stylesheet-abstraction-matters/ - Why Stylesheet Abstraction Matters
http://coryschires.com/why-you-should-deeply-nest-your-css-selectors/ - Why you should deeply nest your CSS selectors
http://woorkup.com/2009/10/31/5-must-read-presentations-about-css-coding/ - 5 Must Read Presentation About CSS Coding
http://sixrevisions.com/web-development/progressive-enhancement/ - Progressive Enhancement 101: Overview and Best Practices

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License