Before I wrote our Sass & CSS Style Guide, I read up on a fairly old methodology for authoring CSS called SMACSS. I fell in love with SMACSS and have been using my own version of the methodology ever since.
One of the best parts of SMACSS is the concept of modules. That’s what this post is about.
How most of us were (and are) doing it wrong
I still see many web designers writing their CSS for pages, not modules within the page.
I’ll often see CSS that looks like this:
I guess there are some scenarios where this is OK, especially if you’re dealing with a tiny site that only has a few pages and will never grow from there. My experience though is that the website owner will continue to add more pages over time (without ever removing any).
When this starts happening, maintaining the list of page-based styles becomes quite cumbersome. Re-use of styles can get really tricky. What if I want something similar to the home page on another page? The web designer can either copy and paste the styles into the page-based styles (yuck), or he could refactor the CSS into something that can be used by both pages. But then he needs to go change the markup on the old page to make sure it uses the new style. And so on.
The last downside of this page-based approach is that of specificity. To add styles to a page, you need to keep repeating the page’s overall chain of selectors, especially if you need to override a property later.
CSS Tricks demonstrates this nicely, so I’ll repeat Chris Coyier’s example.
And the CSS demonstrates how ugly things can get:
The new world order with modules
With the SMACSS modules concept, you create a class name for the module and then namespace related classes using that module name at the beginning.
In HTML, you get constructs that look like this, using a
bio module as an example:
You end up with a root
bio class that has several related classes:
From there, it’s pretty easy to style as needed. Using Sass, you can create an easy-to-find module file at
scss/modules/_bios.scss that may look something like this:
Now you’ve created a module that can exist on just one page or can be applied anywhere you want on the site.
And because all styles are “flat” in specificity, it’s easy to override styles as needed later in the cascade. (Hey, you also get a little performance boost too.)
Developing styles for different contexts and states
Sometimes you may want to alter the way a module displays slightly based on its context or even based on some sort of state.
Sass’s nesting syntax makes it practical to mix those rules right in with your modules:
I prefer keeping state classes prefixed with
has- so they’re easy to identify as states. I tend to nest states within their parents (
.discount.is-selected) because state names often have generic names (
is-active) and thus could easily conflict with another module’s state. (For example, we don’t want
.discount.is-selected to clash with
Because contexts are namespaced with the module name, they can stand alone without being nested. Making the nesting structure of classes as flat as possible keeps behavior more predictable as you maintain the styles over the long term.
How modules change estimates of effort
While consulting, I’ve had to come up with many estimates for implementing HTML for a website or web application. I used to look at the general number of pages and say, “Eh, it usually takes me X hours for the home page, Y hours for specialized pages like this, and Z hours for more general pages.” Then things usually got out of hand, and I always ended up spending more time than estimated.
While I still hate coming up with estimates, I have found that it gets a little easier if I can break down my planned work into smaller pieces and estimate the effort for each piece.
More formalized methodologies
If you prefer wearing a bowtie while developing CSS, there are some more formal methodologies to building modular classes:
I think that SMACSS adds just enough structure to keep things under control without going overboard like the others do. But your mileage may vary, so give those links a peruse and don’t be afraid to form your own opinions.