wiki:CssRules
Last modified 13 years ago Last modified on 01/19/12 16:35:22

CSS Conventions and Best practices

These rules are the ones used by the Social Book project... I think there should be one place (for example the Astea wiki in which rules applying to different programming languages, methodologies and etc should be listed and used by all the Astea teams)

These general guidelines and rules aim to facilitate our CSS readability, maintainability and reusability. Developers should follow them, while writing CSS styles, and reviewers should verify the implementation, according to them, while reviewing CSS styles.

General

  1. Use /* CSS comment here */-style comments.
    • If the comment applies for a single property, having the comment on the same line is allowed, if this won't break rule 2 (see below).
  2. Strive not to have horizontal scrollbars in the CSS files you write/edit.
    • Nota Bene: When there is no hard limit enforced, different combinations of resolutions and editors will show horizontal scrollbars differently.
  3. Use 1 tab (4 spaces) for indentation.
    • Most editors can automatically put spaces, when you press the TAB key.
      • Different handling of the tab whitespace character on different clients make it less desirable for indentation, compared to 4 spaces.
    • 2 spaces seems to be too little for CSS, as style declarations generally aren't that big or complex.
  4. First structure your layout and content, then create the presentation specifics.
    • This is the most often seen best practice on the subject :)
  5. Validate your CSS with the W3C Validator.

CSS files ordering

  1. Dividing CSS styles in many files for development purposes is allowed, but concatenate and minify for production.
    • Separate based on semantics, in order to promote writing reusable CSS, but be careful not to create too many levels of separation.
      • For example, all styles for our common header could be put in header.css, however creating two different CSS files for our coverflow and its control components, when, as of the time of writing this, they are always used together, is unnecessary.
  2. Adding new CSS files should be done relatively rare.
    • Essentially, all our CSS files should belong to one of the following groups: a General placeholders for project-specific styles.
      1. General CSS file for a given page (user_home.html, store.html, etc.), named after the corresponding page.
      2. CSS file, styling some reusable component (cover_flow.css, button.css, etc.), named after the corresponding reusable component.
      • This will allow reusing CSS styles, while avoiding having to work with/maintain/check when adding or editing a property a ton of superfluous CSS files.
    • Before adding new CSS file, think about whether the file styles will be required in another page and whether you are violating the rule of the "Holy Тrinity".
  3. Think about allowing "theme-ing" to the application.
    • When something is identified as customizable or being good candidate for applying changeable themes, it should be carefully designed to allow easy CSS modification.
    • Most likely, this will affect the first group of the aforementioned types of CSS files - general placeholders for project-specific styles.
  4. CSS reset should be used only if issues, identified with different browser default styles are identified.
    • Otherwise, it affects performance (as it should be separated from the other styles, which means one more HTTP request) can be cause for subtle bugs and is very close to premature optimization.
    • See here for more musings on the subject.

CSS style names

  1. Use camelCase for delimiting complex CSS class names or ID references.
    • Some older browsers may have problems or may not support underscores, so they are not an option.
    • As for camelCase versus hyphens, there are arguments for and against both of these, but camelCase seems to be consistent with:
      • currently existing DOM elements IDs and CSS style names
      • conventions in other platforms that we use (for example Java).
    • You can take a look at some of the pro camelCase or pro hyphens arguments.
    • Nota Bene: This also affects the naming convention for DOM element IDs.
  2. Name classes or DOM elements semantically.
    • Don't use names like grayBlock or blueLink, as they couple content with content presentation.
    • Think about what are you styling and not how are you styling it.
  3. Avoid using very specific selectors, (which usually use HTML element type selectors).
    • Don't use div#page div.teaser ul.products li p.name, prefer ul.products p.name instead.
      • This way, you avoid coupling your styles with the structure of your markup.
    • Using very specific selectors also makes it very hard to "cascade" your styles and override them in a more natural way.
  4. Apply namespacing, if needed, only to the names of reusable styles.
    • If the conventions for CSS files and hierarchy are being followed, collisions may occur only from adding link to a reusable CSS file.
    • The namespacing convention for the reusable identifiers and classes is a variation of the Hungarian notation. Instead of actual data type, however, we'll be encoding the type of reusable component, that will be styled.
      • For example, classes for the coverflow reusable component are prefixed with cf, so the metadata will have the class cfMetadata applied.
      • The namespacing prefix is not constrained to only 2 symbols, for example class, which disables a reusable button may be called btnDisabled.
      • Using @namespace at-rule is not recommended as it affects the layout markup syntax, in order to create XML namespaces.

CSS style ordering

  1. Apply narrowly the style that you're writing and consecutively check whether it can be broadened.
    1. Start by applying the style that you're writing by ID.
      • Don't arbitrarily add IDs to elements just to be able to style them by ID - if they don't display relatively big or important piece of data, first check whether you can use type style or class.
    2. Search the style declarations of the page or component that you're styling for similar DOM elements with similar styles.
      • If you find such, change the style to type selector.
    3. Search all style declarations for some of the most-specific CSS properties of your style.
      • If you have a match, check whether the styles can be abstracted into a reusable class style and if yes, create one such style in the corresponding CSS file.
    • All of these steps can be made much easier by being acquainted with the designs that have to be implemented and the general project style.
  2. Don't order your CSS styles according to the layout of the markup that you are styling.
    • Otherwise, you are coupling your styles with the structure of your markup.
    • Also don't use selector-based indentation, as this is essentially the same thing (with the same problem)
  3. First level of ordering - separate different rule blocks.
    • Group all element styles first. are grouped by the type of tag.
    • Group all classes second.
    • Group all ID styles third.
  4. Second level of ordering - within the identified rule block groups.
    • Element styles are grouped by the type of tag.
    • Classes are grouped by their affect.
    • ID styles are grouped by page components.
      • The components are identified semantically and independent from the page layout.
  5. Add comment headers, separating the different groups and components.
    • You may prefix with a special character, in order to facilitate searching in the CSS file.
      • For example, you can use /* =NAV */, instead of /* NAV */.

Here's an example of such style grouping and ordering, based on the aforementioned rules:

  • General styles (Element styles)
    • body styles
    • links
    • headings
    • other types of tags
  • Helper styles (Classes)
    • forms
    • notifications and errors
    • classes, used for more than one element, specific to this page
  • Page structure
    • page skeleton styles
  • Page components (ID styles)
    • most of the styles for the page here

CSS styles

  1. Always comment browser hacks or specific behavior workarounds.
  2. Avoid !important.
  3. @-rules.
    1. @font-face:
      • Separate @font-face declarations, in order to facilitate caching (as fonts usually are big, compared to CSS, JS or HTML files).
      • If the fonts are relatively small, they can be inlined as base64 string, so that minimum HTTP requests are made.
      • Local check for the specific font family can be included, in case the user already has the font.
      • See here, here and here for some more musings on the subject.
    2. @import:

CSS properties

  1. Put every property on its own line and put a single space between the property and the value (after the colon).
    • This increases readability and if minification is used, doesn't affect file size/performance.
  2. Order of properties.
    • We should choose one of the two possible approaches to ordering CSS properties:
      1. Ordering alphabetically
        • Pros: easy to do, helps you find a single property very fast
        • Cons: separates some logically related properties
      2. Ordering functionally
        • Pros: helps you to easy identify what exactly the style does, can be used to better recognize potential tautologies or bugs
        • Cons: not very easy to maintain, has much steeper learning curve
        • See here and here for some examples of such property ordering style.
  3. Use shorthand properties by default, but keep in mind longhand properties.
    • Longhand properties can be useful:
      • For debugging purposes, as overriding is much more visible, when specific "sub"-properties are on different lines in the style declaration.
      • Where inheriting only a part of the specific "sub"-properties, as otherwise the shorthand version will have to include the inherited property explicitly, effectively duplicating definitions.
      • See this article for more info on shorthand properties.
  4. font-size measurement unit.
    • From the four available measurement units (ems, percents, pixels and points), points are generally recommended against.
    • ems and percents (relative)
      • Pros: more flexible in theory (can scale much better in case the default font size can vary a lot - for example on mobile devices or if accessibility options are used)
      • Cons: can suffer from non-obvious DOM parent-child relationships (so that the pre-set font-size is unexpected), can be much harder to scale non-abrupt (0.938em and 1.064em also look weird in your CSS).
      • Generally, percents scale more
    • pixels (fixed size)
      • Pros: already used in our project, designs are specified using pixels, easy to set to an expected value, users can zoom in/out as browser feature
      • Cons: can be a problem on high-density mobile devices, disregard user accessibility options
    • My personal preference is towards ems, but I think we should stick to pixels for this project.
    • See here, here and here for more musings on the subject.

Remaining topics

  • Color values
  • Class-itis and div-itis
  • float and clear
  • IE specifics
  • CSS sprites
  • ?

References and sources

  1. http://natbat.net/2008/Sep/28/css-systems/
  2. http://msdn.microsoft.com/en-us/scriptjunkie/ff679957
  3. http://www.lukew.com/ff/entry.asp?1379 ("Don't blindly follow best practices" reminder)
  4. http://www.phpied.com/css-coding-conventions/
  5. http://net.tutsplus.com/tutorials/html-css-techniques/5-tips-to-writing-better-css/