Skip to main content

Modular CSS: Thoughts on SMACSS modules


My understanding of CSS modules continues to grow from day to day. To me, modules are one of the best ways to create scalable and reusable styles. The offer us a way to add order to our styling. I wanted to jot down a few things I’ve learned about modules.

Lego Bricks

Source: Wikipedia

What are modules?

If you’ve read through SMACSS, the concept of modules is already familiar. They are one of the main categories of styles in SMACSS. Below is a snippet on modules pulled from the SMACSS book:

Modules sit inside Layout components. Modules can sometimes sit within other Modules, too. Each Module should be designed to exist as a standalone component. In doing so, the page will be more flexible. If done right, Modules can easily be moved to different parts of the layout without breaking.

Modules make up the majority of a website’s styles. They help us create code that we can extend and scale.

Another interesting point Snook talks about is how “Modules generally don’t have a width specified. They’re designed to contain content and sit within a layout, which provides constraints to the modules.”

Modules, OOCSS and Structure vs. Skin

One of the main principles of Object Oriented CSS is the separation of structure and skin.

From Nicole Sullivan’s OOCSS Wiki:

Separate structure and skin

This means to define repeating visual features (like background and border styles) as separate “skins” that you can mix-and-match with your various objects to achieve a large amount of visual variety without much code

We can apply this concept of separate styles for structure and skin to modules.

Harry Roberts explains way better than I could about how you can combine the concept from OOCSS with modules.

The following is from Harry’s CSS Guidelines:

As an analogy (note, not example) take the following:

css
.room {
}
.room--kitchen {
}
.room--bedroom {
}
.room--bathroom {
}

We have several types of room in a house, but they all share similar traits; they all have floors, ceilings, walls and doors. We can share this information in an abstracted .room class. However we have specific types of room that are different from the others; a kitchen might have a tiled floor and a bedroom might have carpets, a bathroom might not have a window but a bedroom most likely will, each room likely has different coloured walls. OOCSS teaches us to abstract the shared styles out into a base object and then extend this information with more specific classes to add the unique treatment(s).

So, instead of building dozens of unique components, try and spot repeated design patterns across them all and abstract them out into reusable classes; build these skeletons as base ‘objects’ and then peg classes onto these to extend their styling for more unique circumstances.

In the example above, the .room class Harry talks about would be a module in regards to SMACSS. It contains all of the common styles for all instances of the .room module. We extend the use of the .room module by adding a modifier to it, .room–kitchen, .room–bedroom, .room–bathroom.

Module modifiers contain the specific styles for each instance of the .room module. These are usually “skin” based styles.

Module Modifiers

As I talked about earlier, module modifiers extend the use of modules. There are a few ways that come to mind on how one could use module modifiers.

Sample reviews component design

For example, with the above comp, we could create a reviews module that had all the styles for the movie review block in it, and create module modifiers for albums and books.

html
<div class="reviews">
<h2>Movie Reviews</h2>
...
</div>
<div class="reviews reviews--albums">
<h2>Album Reviews</h2>
...
</div>
<div class="reviews reviews--books">
<h2>Book Reviews</h2>
...
</div>
css
.reviews {
/* Module styles, plus specific styles for .reviews--movie */
}
.reviews--albums {
/* Overrides for the albums block */
}
.reviews--books {
/* Overrides for the albums block */
}

Another option is to create a module just for reviews which contains all the shared styles and no specific styles, then create a modifier for movies, albums, and books.

html
<div class="reviews reviews--movies">
<h2>Movie Reviews</h2>
...
</div>
<div class="reviews reviews--albums">
<h2>Album Reviews</h2>
...
</div>
<div class="reviews reviews--books">
<h2>Book Reviews</h2>
...
</div>
css
.reviews {
/* Common module styles */
}
.reviews--movies {
/* Specific styles for movie reviews block */
}
.reviews--albums {
/* Specific styles for album reviews block */
}
.reviews--books {
/* Specific styles for books reviews block */
}

I’m not particularly sure which method I prefer the most. With the first method, I see having to always overwrite the unique styles in each instance from the core module.

With the second method, each time you use a module, you would need to include a module modifier with it as the module only contains the shared styles, and no unique styles for individual instances.

If you have any thoughts on which method you prefer or think would be better, let me know in the comments below.

In both examples, .reviews is our module. In a previous post I talked about how we can use class attribute selectors to reduce the number of classes in our HTML. Below is an approach I’ve been using which uses class attribute selectors. In the example, we no longer need the .reviews class in our HTML, we can use [class*='reviews--'] instead for the same purpose.

html
<div class="reviews--movies">
<h2>Movie Reviews</h2>
...
</div>
<div class="reviews--albums">
<h2>Album Reviews</h2>
...
</div>
<div class="reviews--books">
<h2>Book Reviews</h2>
...
</div>
css
.reviews,
[class*='reviews--'] {
/* Common module styles */
}
.reviews--movies {
/* Specific styles for movie reviews block */
}
.reviews--albums {
/* Specific styles for album reviews block */
}
.reviews--books {
/* Specific styles for books reviews block */
}

I like to keep the .reviews in my styles if, for whatever reason, I decide to use it in my HTML. Whether you use multiple classes or class attribute selectors, the choice is up to you. What is important is understanding the concept of a module and a modifier.

In an earlier post, a commenter posted about selector performance of class attribute selectors. It is true that class attribute selectors are slower than class selectors but I would not worry about CSS selector performance. Ben Frain has a great write up on CSS selector performance that explains why you shouldn’t worry about selector performance in CSS better than I could. After reading it, especially the comment from Webkit Engineer, Benjamin Poulain, I no longer concern myself with selector performance.

Nathan Ford also has some insightful comments on selector performance of class attribute selectors in his A Harder Working Class post on 24Ways.

Naming Conventions of Modifiers

What I call module modifiers, Johnathan refers to as submodles. I use the term modifier based on my understanding of the BEM methodology. I think as long as you understand the concept of modules(blocks), submodules(modifiers), and sub-components(elements), what your call them is up to you. Find a naming convention you and your team agree on and stick to it. As long as it is easy for you to understand when you come back to your code or for other developers to understand if they work on it, that is what is important. In the recent SMACSS newsletter, Johnathan listed some other naming conventions people are using.

Modules and Presentational Class Names

Another concept in OOCSS is the use of visual class names, or presentational class names. Ask anyone about semantic class names and they will tell you presentational class names are a bad practice, and I agree, to an extent. While I think presentational classes should be avoided in the HTML markup, I think they play a big role in aiding in developer understanding of the styles. They add meaning (semantics) for developers on how certain elements will look. People generally don’t like presentational classes because they can muddy up our HTML. If we ever decide to change the look of something, we need to modify the HTML and this isn’t always possible/ideal. So where do presentational classes fit in?

%placeholders

With the rise of CSS preprocessors, specifically Sass, the ability to craft intelligent CSS has grown immensely. I especially like the %placeholder feature of Sass. Using placeholders, we can keep our presentational class names, though extend them inside our “semantic” role based class names.

Ian Taylor has a great article on how we can use presentational classes inside of role based class names. I see it as a way to include presentational class names inside of module classes.

I know Semantic.gs uses the same approach of loading presentational classes inside role based class names with preprocessors and Jeff Escalante wrote about this concept about a year ago as well.

It is definitely something I’d like to explore some more.

Modules within Modules vs. Sub-components

Another important markup feature Snook talks about are sub-components. These are the inside parts of the modules, the pieces that make up the module. Also of note is that modules can be used inside of other modules as well. I need some more experience using modules and sub-components to form my thoughts on best practices for when to use sub-components and when to use a module inside a module.

Going back to the reviews example, each review is a module and in each of the .review modules there is a button. Depending on how you look at it, the button could be its own module used within the .review module, or it could be a sub-component of the .review module.

In another post I’ll come back to looking at modules within modules vs. sub-components.

This is really just a brain dump on my understanding of modular CSS. I find, writing this all done helps me better understand the concepts. As always, I’d love to hear your thoughts and ideas on this topic.

Tags: CSS