Skip to main content
Ben Nadel at cf.Objective() 2017 (Washington, D.C.) with: David Colvin
Ben Nadel at cf.Objective() 2017 (Washington, D.C.) with: David Colvin

Scalable And Modular Architecture For CSS (SMACSS) By Jon Snook

By
Published in Comments (5)

CSS, or Cascading Style Sheets, has made formatting our web content much easier than it used to be. And while it is relatively simple to get up and running with CSS, it is a technology that appears to be a bit more art than science. As our applications grow in size and complexity, keeping rules clean, organized, siloed, and DRY (Don't Repeat Yourself) can become a bit of a Herculean task. People like Nicole Sullivan (Object Oriented CSS) and Jon Snook (Scalable and Modular Architecture for CSS) have tried to bring a method to the madness with their own CSS frameworks and style guides.

I love cascading style sheets; but, I am certainly not that great with them. I can get things done; but, doing so often requires a CSS file with thousands of lines of code in it. I know there must be a better way; so, when I saw that Jon Snook - Yahoo! client-side CSS and JavaScript expert - had published a new book, Scalable and Modular Architecture for CSS (SMACKS), I immediately purchased it.

At 70 pages, the book is a really fast read and is quite easy to understand. Snook does a good job of laying out his approach, breaking down concepts, and providing examples for illustration. I really liked a lot of what he was saying and definitely have some key take-aways to bring into my next web development project.

There were, however, a few concepts that I had trouble wrapping my head around. The biggest stumbling block for me was the concept of State. When I write CSS, I tend to think of State as a sub-classing of a given module (or part of a module). So, for example, if I had the following toolbar module:

div.toolbar { ... }

... I might have an "inactive" state sub-class version named:

div.toolbarInInactive { ... }

Notice that I have append the term "InInactive" to sub-class the toolbar module. The state, in this case, is highly coupled to the module.

In the SMACSS book, Snook talks about State as being a broadly applicable concept. So, rather than having an "inactive" state for the toolbar, an application might define a general inactive state concept:

.s-inactive { ... }

Notice that States in the SMACSS style guide are prefixed with "s-". To apply this state to my toolbar, I might then have markup that looks like this:

<div class="toolbar s-inactive"> ... </div>

Here's where my experience with and my understanding of large-application CSS really starts to fall short. At a philosophical level, I like that this approach would create a cohesive and consistent look throughout an application; but, at a practical level, I have no idea how one would even think of, let alone define such far-reaching styles.

Furthermore, I have trouble imagining that two different modules would implement a given state in the same way. One might implement "inactive" by hiding itself; another might implement "inactive" by lowering its opacity; and still, another might implement "inactive" simply as a JavaScript hook rather than as a visual distinction. As such, the state concept would have to be overridden for each module - a point that seems to negate the need for any global sense of the given state.

State aside, there are definitely a lot of good points in the book. More than anything, perhaps, I like the way that the SMACSS style guide gets me to start thinking about my CSS code in terms of what role a given rule will be playing: Base, Layout, Module, State. In fact, this makes me want to start breaking my CSS modules up into a more modular file system. Perhaps this is a perfect segway into something like LESS or SASS!

Want to use code from this post? Check out the license.

Reader Comments

17 Comments

The trick to making that work isn't to make sure that the entire app defines the inactive state as the same on every single element, but to define multi-class rules to make specific inactive display rules. So you would have div.toolbar, and div.toolbar.inactive.

So you can have multiple inactive rules across different elements:

div.toolbar.inactive {}
input.clickme.inactive{}

etc, etc, etc.

71 Comments

What's kind of funny here is that CSS has always been traditionally "desginer-friendly". And this is the second recent article I've seen where a developer-centric mind tries to "develop-ize" CSS.

The previous article I saw talked about OOCSS (Object-oriented Cascading Style Sheets) and I actually said out loud "You have GOT to be kidding me."

In the end, where there is truth in the need to separate structure from style and to keep one's CSS code organized and optimized, I've yet to see justification for needing another new acronym in an already oversaturated market.

I'm sure this all derives from an obsessively compulsive desire to ensure that the frameworks we develop with are as optimized and easy to implement as possible.

15,919 Comments

@Daniel,

I definitely like the idea of applying multiple class names in that manner. I think (from what I recall from the book - Snook mentions this) that only prohibits IE6. That seems pretty good to me. It's like sub-classing, but makes it a bit more "semantic", which is nice.

@Aaron,

Ha ha, it's hard as a developer to not find the "one" way to do something. It just feels safe; plus, it can make this stuff feel easier. Of course, even Snook says in the book that there is no "one" way and that even his recommendations can be taken in part or in whole.

290 Comments

@Ben,

Notational comment: You can "AND" pseudo classes the same way as you AND classes (@Daniel's examples):

selector:pseudo_class_one:pseudo_class_two

That said, watch out for "::something". It looks like it contains some sort of null pseudo class, but actually it's a newer notation for a pseudo element. Pseudo elements and pseudo classes used to both be prefixed with a single colon, but to PREVENT confusion, pseudo elements can now use the "::" prefix. Prevent, hahahaha.

Maybe I was the only person who got confused by "::". But in case it helps someone else, just sayin', that's what it is.

1 Comments

I agree with Daniel here in that I find it useful to view something like .s-inactive as a kind of superclass. I like to setup a default value for .s-inactive and work from there.

For example:

.s-inactive {/*PLACEHOLDER DO NOT CHANGE: use more specific rules below*/}
.toolbar.s-inactive {filter:alpha(opacity=50); -moz-opacity:.50; opacity:.50;}

I find it makes a great warning for the coders that come after me to discourage the bad things that can happen if we set values for it later on in the file:

.toolbar.s-inactive {filter:alpha(opacity=50); -moz-opacity:.50; opacity:.50;}
.s-inactive {color:#933;background-color:#ffc;}
I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel