Monday 19 March 2012

An Introduction To SMACSS Guidelines For Writing CSS | Van SEO Design

An Introduction To SMACSS Guidelines For Writing CSS | Van SEO Design


An Introduction To SMACSS Guidelines For Writing CSS

Posted: 19 Mar 2012 05:30 AM PDT

In recent weeks I’ve been discussing ideas and approaches to writing css. I’ve looked at abstracting css and talked in some detail about Object Oriented CSS. If classic css sits on one side of an approach to writing css and OOCSS sits on the other, SMACSS sits somewhere in the middle.

While I’ll do my best to cover the basics here, I’d recommend reading through the SMACSS documentation. It’s not a long read and of course it is the original source. You can also listen to SMACSS creator, Jonathan Snook, talk about it on the premiere episode of the ShopTalk podcast.

As with my OOCSS post, this one is more research on my part than any actual practice.

Modular lego building

What is SMACSS?

SMACSS stands for Scalable and Modular Architecture for CSS and it has 2 core goals.

  • Increase the semantic value of a section of html and content
  • Decrease the expectation of a specific html structure

Like Object Oriented CSS, SMACSS is an approach to writing css and html with more emphasis placed on using classes. Unlike OOCSS, it doesn’t suggest using classes for everything. It’s fine with IDs and descendent selectors where appropriate.

At the very core of SMACSS is categorization. By categorizing CSS rules, we begin to see patterns and can define better practices around each of these patterns.

Much like OCCSS, the purpose of this categorization is less code repetition, a more consistent experience, and easier maintenance. Under SMACSS there are 5 general categories of css rules.

  • Base — These are your defaults (html, body, h1, ul, etc)
  • Layout — These divide the page into major sections
  • Module — These are the reusable modular components of a design
  • State — These describe how things look when in a particular state (hidden or expanded, active/inactive)
  • Theme — These define things like a color scheme or typographic treatment across a site

Most of us tend to mix styles across all of these categories, which creates complexity. If instead, we can understand the differences in these categories and apply some guidelines to each we can simplify our css.

Jonathan offers a naming convention for working with SMACSS, though he’s quick to point out you don’t need to follow his convention. He does feel that having some consistent naming convention is important.

  • Base — Nothing needed
  • Layout — l- or layout- prefixes
  • State — is- prefix as in is-active or is-hidden
  • Module — Modules just use module name ( .callout ) instead of trying to prefix each, however related modules receive a consistent prefix to help organize them

Let’s dig a little deeper into the guidelines for each of the categories.

Base Rules

Base rules are applied directly to elements through element selectors, descendent selectors, child selectors, pseudo-classes, however not specific class or ID selectors.

As the name implies these are the base or default styles for elements. CSS resets are an example of base styles. Base styles are pretty simple and probably aren’t much different than what you already do under classic css.

Simple 2-column layout, with header, footer, left sidebar, and main content area

Layout Rules

There are major and minor layout components in every design. A header block would be a major component, while the combination of logo and tagline within the header would be a minor component. The layout rules of SMACSS apply to major components. Minor components fall under the module rules we’ll get to momentarily.

The amount of reuse can also determine which blocks are major and minor parts of the layout. More repetition should lead you to think module over layout and classes over IDs. However, SMACSS doesn’t limit IDs to behavioral hooks. It sees them more in traditional css terms. Single use calls for IDs. Multiple uses call for classes.

Generally a layout style will have a single selector (either an ID or class). Additionally there could be a style set to allow the layout style to respond to different factors.

 #sidebar { width: 20%; } .l-fixed #sidebar { width: 250px; } 

The above would allow for a change between flexible and fixed layouts.

Jonathan walks through an example from a Featured section on CNN’s website, which is worth looking over in more detail. The html for the section is as follows:

 <div>   <h2>Featured</h2>   <ul>     <li><a href=""></a></li>     <li><a href=""></a></li>   </ul> </div> 

and the corresponding css:

 div#featured ul {   margin: 0;   padding: 0;   list-style-type: none; } div#featured li {   float: left;   height: 100px;   margin-left: 10px; } 

Familiar stuff and probably similar to html and css you’ve written before. There are 3 assumptions with the above code.

  • there will only ever be one featured section on page
  • list items in the section are always floated to the left
  • list items in the section always have a height of 100px

These assumptions might be reasonable for small sites, but become less reasonable as sites grow larger and more and different people work on them. SMACSS guidelines would instead suggest the following css after adding the l-grid class to the container div.

 .l-grid {   margin: 0;   padding: 0;   list-style-type: none; } .l-grid > li {   display: inline-block;   margin: 0 0 10px 10px; } 

There’s an additional IE7 hack on ,l-grid > li, which I haven’t shown here. According to Jonathan, the SMACSS styles improve things because:

  • The grid layout can now be applied to any container to create a float-style layout
  • The depth of applicability has been decreased by 1 (more on this below)
  • The specificity of the selectors has been reduced
  • The height requirement has been removed allowing each row to grow to the height of its tallest item.

le Corbusier's modular man

Module Rules

Again modules are built around minor page components like navigation bars and widgets. They tend to be inside layout components and even within other modules.

Modules should be designed so they can exist on their own, which gives them greater flexibility in being combined and moved around to different parts of the design without breaking the layout. With modules we do want to avoid IDs and element selectors. More reuse means classes.

Where you can reasonably predict what html elements will be used it’s ok to use descendent selectors as in .module span, but as projects grow things will quickly become less predictable and so it becomes limiting to attach element selectors to module classes. The more generic the html selector (such as div or span), the more likely there will be a conflict.

Subclassing Modules

Modules are for reuse and naturally we’ll want to reuse modules in different sections of our layouts When we do, we might reach for the parent element to modify the style.

 .box { width: 200px; } .box ul { width: 100px; } #sidebar .box ul { width: 200px; } 

This can quickly lead to specificity issues. Better would be to subclass the box module and apply the subclass.

 .box { width: 200px; } .box-contstrained { width: 100px; } 

With sub-classing both the base module and the sub-module class names get applied to the html element (Presumably there would be more styles on the base module than shown here). As we saw with OOCSS we want to avoid css based on location and subclasses help us stay away from location based css.

Poster for State of Monc live recording in Lantaren venster

State Rules

A state style is one that augments or overrides other styles under given conditions. For example an accordion with collapsed and expanded states. These are typically applied to the same element, should be built to stand alone, and are usually developed on a single class selector.

Jonathan presents a more complete example of a calendar structured in html as a table. Here’s I’ll simply present 3 selectors to show the main idea behind state rules

 .cal td { } .cal td.cal-today { } /* overrides the default for a specific cell */ .is-selected td { } /* overrides the default for a state change */ 

State changes are represented in one of three ways:

  • Class name — The change happens by adding or removing a class, usually with Javascript
  • Pseudo-class — The change happens to elements that are descendants or siblings of the element with the pseudo-class
  • Media query — The change happens under defined criteria, such as different viewport sizes.

There’s a lot more detail on the SMACSS site, which I’ll again encourage you to read. I would like to point to a couple of things Jonathan says about changing states, which I found interesting.

When you actively ask yourself, “what is the default state,” you find yourself thinking proactively about progressive enhancement

He closes the SMACSS section on changing state with:

Thinking about your interface not only modularly but as a representation of those modules in various states will make it easier to separate styles appropriately and build sites that are easier to maintain.

More than anything I think both SMACSS and OOCSS are about getting us to rethink our css practices and it’s this thought, above any specific guidelines and rules, that will prove to be the most valuable take away.

Theme Rules

Theme rules are similar to state rules in that they describe how layout and modules might look. However, they aren’t used as often within a single project and so Jonathan doesn’t consider them as part of the core types.

Theme rules would define colors or typography across a site and separating themes into their own set of styles can allow them to be more easily modified. If you remember this concept of being able to change all color styles to create a new color scheme or simply experiment while learning is what led me into all this recent css exploration in the first place.

Random ball bearings shown through depth of field

Depth of Applicability

One of the things that comes up with greater emphasis on classes is the coupling between css and html. It’s something I mentioned previously when talking about our flawed css practices. Is this coupling really about our use of classes over element selectors or is something else at play?

 #sidebar div { border: 1px solid #333; } #sidebar div h3 { margin-top: 5px; } #sidebar div ul { margin-bottom: 5px; } 
  • The above relies on a specific html structure
  • There is a greater depth of html selectors than necessary

It’s more this depth of applicability (the number of generations affected by a given rule) that increases coupling.

Consider the html below.

 body.article > #main > #content > #intro > p > strong { } 

The depth of applicability is 6 generations. Even if the the selector is written as .article #intro strong, the depth is still the same 6 generations.

The greater the depth, the greater the dependency on a given html structure. This is what strongly couples html and css and is what we’d like to avoid. It means page components can’t be moved and that more duplication of code is likely.

A greater use of classes ultimately reduces the depth of applicability, leading to more flexible styles. It may seem counterintuitive as we’re adding extra markup to html with classes, but this frees us from relying on specific html structures.

 p.module > strong { } 

Above the module class could be added to any paragraph, reducing depth and increasing flexibility.

Thought bubble spray painted on a brick wall

Closing Thoughts

As I mentioned with OOCSS let me remind you again that what you see here is based on research and not actual practice. In the coming weeks I’d like to take a simple layout coded in classic css and recode it under both OOCSS and SMACSS guidelines to gain a little more perspective from real practice.

Doug Avery of Viget, posted some thoughts about both a few months back based on actual use. It’s a good read to understand some of the pros and cons and differences between classic css, SMACSS, and OOCSS.

Both OOCSS and SMACSS share some common goals and try to help us write more flexible and maintainable css.

I haven’t quite wrapped my head around either yet, though both make sense to me as a better approach to writing css. Both urge us to make better use of classes. SMACSS pulls back some from using classes for everything, reserving them mainly for modules and states.

This is still exploration for me. My early guess is that while I like the ideas behind both OOCSS and SMACSS, I’ll ultimately settle on something of my own creation based heavily on the same underlying principles. It’s the underlying principles I’m most interested in.

I also get the feeling that once I’ve spent more time with css preprocessors the whole picture of a new approach to css will become clearer to me.

Have you used SMACSS in your projects yet? If so, what do you think? How does it compare to OOCSS?