An Introduction To SMACSS Guidelines For Writing CSS

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.

{code type=css}
#sidebar { width: 20%; }
.l-fixed #sidebar { width: 250px; }
{/code}

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:

{code type=html}

Featured

{/code}

and the corresponding css:

{code type=css}
div#featured ul {
margin: 0;
padding: 0;
list-style-type: none;
}

div#featured li {
float: left;
height: 100px;
margin-left: 10px;
}
{/code}

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.

{code type=css}
.l-grid {
margin: 0;
padding: 0;
list-style-type: none;
}

.l-grid > li {
display: inline-block;
margin: 0 0 10px 10px;
}
{/code}

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.

{code type=css}
.box { width: 200px; }
.box ul { width: 100px; }
#sidebar .box ul { width: 200px; }
{/code}

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

{code type=css}
.box { width: 200px; }
.box-contstrained { width: 100px; }
{/code}

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

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

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?

{code type=css}
#sidebar div { border: 1px solid #333; }
#sidebar div h3 { margin-top: 5px; }
#sidebar div ul { margin-bottom: 5px; }
{/code}

  • 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.

{code type=html}
body.article > #main > #content > #intro > p > strong { }
{/code}

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.

{code type=html}
p.module > strong { }
{/code}

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?

« »

Download a free sample from my book, Design Fundamentals.

13 comments

  1. I was writing non-reusable code at the beginning of coding career, I wasn’t thinking that project can extend and scale. Until I tried Wordpress, then I realized I need to adhere to class naming. Also started slowly to move from classic style to SMACSS.

    I’m still trying to find balance between old and new coding style.

    • I hear you. I didn’t start out writing reusable code and even now I’ll still add in something just because it works.

      It’s not the easiest transition, but I’m trying to get better at writing scalable code.

  2. Hi I enjoyed your post. But is there any site where we can qualify the code being produced?

    Because reading the theory is very good, but how do you know if the content we’re generating is consistent with the proposed or simply whether what we’re doing is good or is under the influence of our old behaviors.

    • Thanks Giancarlo. I’m not sure what you’re looking for. Do mean something like a site to validate code? I think in the end you have to decide for yourself if the way you’re writing code is any better of still pretty much influenced by what you’ve always done.

      I would look at SMACSS more as guidelines that have proven to work for someone else and integrate the concepts into your own process. For example having understood the concept of depth of applicability, I’m now more aware of how css selectors affect html and so I tend to write selectors that are less tied to a specific html structure.

  3. Do markup really matter? Sites like facebook or google plus add a lot of “waste” markup and they work fine. In the other hand, I have been able to see how descendant selectors are harder to style and are to rigid to work with. There are some people who argue selectors are slower than classes or ids, so, that is an statement in favor of SMACSS and OOCSS.

    Good reading here.

    • Thanks Francisco. Good question. I think it depends on your point of view. Obviously there are sites that don’t have the most well organized code and the sites run perfectly fine.

      On the other hand more organized code will make the site easier to maintain and it should lead to less code overall. The latter could be a performance gain depending on how much code is saved.

      I think larger sites like Facebook and Google can get sloppy with their code, because it’s probably a lot of different people maintaining it. Sometimes it’s quicker for someone not familiar with the code base to add a line of code that duplicates some other code or is more of a hack than fitting into the system. The a few more people do the same and so on. The more lines of code that aren’t part of the larger system the easier it is for the next person to do the same and little by little the code gets sloppier and sloppier.

      • Sure it is. There should be thousands of engineers working on big companies products. And when that is the case, methodologies like SMACSS, OOCSS or BEM seem to be unusable in their development process, don’t they?

        Making a parenthesis, I have, by casuality, read aboout OOCSS, SMACSS and BEM thanks to you and I am in the process of choosing which technique to use in next developments, Have you already made your mind about which to choose? If so, can you tell why?

        • I think when working with a lot of people on a site then can each be shown in advance the methodology being used. Sure, the more people working on a site, the more likely some will go their own way and not follow the methodology, but as long as each understands it and knows that’s how the code is being written they should be able to keep things consistent for the most part.

          I haven’t entirely follows any of the different techniques. I find it more difficult to change how I code than I thought. I don’t know that any of these methods works exactly as is for me.

          What I’ve done is take bits and pieces from each. I’ve been trying to think more about different elements in a design as objects that I don’t have to code uniquely all the time. I’ve been trying to do a better job in naming classes. Things like that. I wouldn’t say my code is following any of these, but overall I’m learning from them and hopefully making my code more modular.

          • Sure it is complicated to get rid off the habits we have. I am about to start a project and as I am going to introduce BEM to the designer. We are going to use it in order to try it out and see its benefits.

            Thanks for sharing these topics (BEM, SMACSS and OOCSS).

            I’ll share how it is to apply BEM completely when we the project is almost done.

  4. Please do share your experiences when the project is done or close to being done. It’ll be an interesting read.

    I think like most people I’m a creature of habit. Over the years I’ve learned how to slowly evolve my habits to lead to new ones, but sometimes making wholesale changes is difficult. This is one of those things where I’m finding it hard to change wholesale.

    The time I have to really work one of these methods is when I have a project in front of me. However, that’s also the time when I want to be most efficient and I tend to go with what I know, even if what I know isn’t necessarily the most efficient option. It tends to be for that specific moment in time.

Leave a Reply

Your email address will not be published. Required fields are marked *