1 of 12

CSS Best Practices

2 of 12

Goals

  • Semantics (Readability)

The meaning and purpose of a CSS selector should be easy to understand.

  • Modularity (Reusability, flexibility)

CSS rules should be loosely coupled and reusable whenever possible.

  • Efficiency (Performance)

CSS selectors should be efficient. This is more important due to its side effect of improving modularity, which has a bigger effect on performance by reducing file sizes and HTTP requests.

3 of 12

Extreme example: "div *"

  • Too generic. Not readable or searchable.
  • Not modular or maintainable, because now you have to override this rule a million times in other places.
  • Not performant. Browser has to check this rule for each and every element it draws on the page.
  • Solution: use a class name!

4 of 12

Readability

  • Be specific with class names.
  • use ".error-content" instead of ".content". This is more reusable, less ambiguous, and easier to find in searches.

5 of 12

Readability

  • Keep documenting. Whenever you add a new group of classes, leave comments to clarify what they're for, examples of where they're being used, etc.

  • You want people to be able to read your CSS and understand your intentions, just as if you were writing in a programming language.

6 of 12

Modularity

  • Avoid "!important".
    • People add it to override styles that are too specific. The correct solution is to avoid too much specificity in the first place, so you never have to use "!important".
    • If you have to use "!important", document the use-case.

.equal-height-column {

margin-bottom: -99999px !important;

padding-bottom: 99999px !important;

}

7 of 12

Modularity

  • OOCSS
  • The same principles that apply to OO programming also apply here.
    • "div button strong span .callout" is like an inheritance tree that's too deep.
    • A better alternative is ".btn .callout". This way you can move the elements around more easily in the future and the style is not tightly coupled with the DOM tree.

8 of 12

Modularity

  • Separation of container from content
    • Children elements should not depend on parent element for styles.
    • If the child needs an override, extend it with a new class name, e.g. ".alert-error", instead of ".followers .alert".

<div class="followers">

<div class="alert alert-error">

<p class="msg">...</p>

</div>

</div>

9 of 12

Performance

  • CSS rules parse RIGHT to LEFT.
    • As each element is drawn on the page, the browser checks if any CSS rules should apply to it.
    • E.g "div ul li {color: #fff;}"
      • For every li that the browser paints, it checks if it's in a ul, then it checks if the ul is in a div.
    • Try and use a max of 2 selectors to target your element.
      • E.g. '.user-list .list-item'

10 of 12

Performance

  • Don't over-qualify selectors.
    • You can just use ".user-list" instead of "ul.user-list"
    • ".user-container .user-list .user-link" could just be ".user-container .user-link"

11 of 12

Performance

  • Avoid tag selectors, e.g. ".followers span"
  • They are neither performant, nor flexible for future scenarios where you might not want all spans to have this style.
  • Use class names instead. This will make it more readable and reusable as well.

12 of 12

Don't be afraid to refactor!

  • See if a style belongs in a different file.
  • Look for duplicated or unused CSS.
  • If you see something bad, don't be afraid to fix it. This is how bad styles manage to stick around for years.