My Key Takeaways from SMACSS

A seemingly simple language yet a tangled mess of complexity. If you are picturing a giant CSS file from your website, you are on the right track. Yes, CSS can start out as a really simple language to learn but can be hard to master. The CSS chaos starts slowly and seems innocuous at first. Overtime as you accumulate features and more variations on your website, you see the CSS explode and you are soon fighting with the spaghetti monster.

CSS Monster

Luckily this complexity can be brought under control. By following a few simple rules, you can bring order and structure to your growing pile of CSS rules.

CSS Monster

These rules, as laid down by Scalable Modular Architecture for CSS (SMACSS), have a guiding philosophy:

  1. Do one thing well
  2. Be context-free (as far as possible)
  3. Think in terms of the entire website/system instead of a single page
  4. Separate layout from style
  5. Isolate the major concerns for a webpage into layout, modules and states
  6. Follow naming conventions
  7. Be consistent

SMACSS in action

The above principles can be translated in the following ways:

  1. Avoid id-selectors since you can only have one ID on a page. Rely on class, attribute and pseudo selectors
  2. Avoid namespacing classes under an ID. Doing so limits those rules only to that section of the page. If the same rules needs to be applied on other sections, you will end up adding more selectors to the rule. This seems harmless at the outset but soon becomes a habit. Avoid it with vengeance.
  3. Modules help in isolating pieces of content on the page. Modules are identified by classes and can be extended with sub-modules. By relying on the fact that you can apply multiple classes to a HTML tag, you can mix rules from modules and sub-modules into a tag.
  4. The page starts out as a big layout container, which is then broken down into smaller layout containers such as header, footer, navigation, sidebar, content. This can go as deep as you wish. For example, the content area will be broken down further on most websites. When defining a layout rule make sure you don’t mix presentation rules such as fonts, colors, backgrounds or borders. Layout rules should only contain box-model properties like margins, padding, positioning, width, height, etc.,
  5. The content inside a layout container is described via modules. Modules can change containers but always retain their default style. Variations in modules are handled as states and sub-modules. States are applied via class selectors, pseudo selectors or attribute selectors. Sub-modules are handled purely via class selectors.
  6. Naming conventions such as below make it easier to identify the type of rule: layout, module, sub-module or state
    • layout: .l-*
    • state: .is-*
    • module: .<name>
    • sub module: .<name> .<name>-<state>
  7. Be conscious of Depth of applicability. Making the rule deeply nested will tie the CSS to your HTML structure making it harder to reuse and increasing duplicate rules.

An example to tie it all together

Alright, there are lot of abstract ideas in here. Let’s do something concrete and build a simple webpage that needs to show a bunch of contact cards, like below:

Cards

Demo

There are few things to note here:

  • There are 4 modules: card, pic, company-info and contact-info
  • The card module has a sub-module: card-gov, for contacts who work for the government
  • The card and contact-info module change layouts via media queries.
 1 /* ----- Picture ----- */
 2 .pic {}
 3 .pic-right {}
 4 
 5 /* ----- Card ----- */
 6 .card {}
 7 @media screen and (max-width: 640px) {
 8   .card {  }
 9 }
10 .card h4 {}
11 
12 .card-gov {}
13 .card-gov .contact-info {}
14 
15 /* ----- Company Info ----- */
16 .company-info {}
17 
18 .company-info-title {}
19 .company-info-name {}
20 
21 /* ----- Contact Info ----- */
22 .contact-info {}
23 @media screen and (max-width: 640px) {
24   .contact-info {  }
25 }
26 
27 .contact-info-field {}
28 .contact-info-field:after {}

Parallels to OO languages

To me the whole idea of SMACSS seems like an application of some of the ideas from OO languages. Here is a quick comparison:

  • Minimize or avoid Singletons: minimize or avoid #id selectors
  • Instances: tags in html which have a class applied
  • Single inheritance: Modules and Sub-modules
  • Mixins: context free rules via states and layouts

Summary

SMACSS can save you a lot of maintenance headache by following few simple rules. It may seem a little alien at first but after you do a simple project, it will become more natural. In the end, its all about increasing productivity and having a worry-free sleep ;-)

Some resources to learn more about SMACSS: