Creating Modules (Part I)
As a grid-based designer, modularity is a familiar concept to me. There are a variety of applications of modular design in the physical world, from furniture to architecture. Naturally, when I encountered the ideas of OOCSS and SMACSS, a light turned on for me. I’ve been abiding by these principles for a little over a year and I wanted to share my process for creating a CSS module.
First, let’s make the following assumptions:
- This project is new
- We are working from PSDs (or PNGs)
- We have familiarity with the principles of OOCSS and SMACSS
First, I analyze the information that’s on the page and write my HTML accordingly. If you are a designer, this should already be part of your process, but I’ll harp on that in another post. Write your HTML without any considerations for style and presentation. Just get the page structure down. This prevents us from getting ahead of ourselves and writing sloppy modules.
Now that the HTML is written, I then create some base styles for the overall project. I use normalize.css by Nicolas Gallagher as a starting point, but you can use Eric Meyer's Reset CSS or write your own (even better!). In writing modular CSS, I cannot stress enough the importance of solid base styles. Be light handed, refrain from making too many assumptions, but get the basics down—font-size for the main body copy, typographical hierarchy, basic palette, etc.
As we go, we may discover additional styles that felt like modules at first, but can be converted into site-wide defaults. Again, just avoid heavy-handed decisions and keep the selectors simple.
We implemented our base styles based on the PSD/PNG our designer has given us (or maybe you are the designer… +1 for you!). Now, review the mockup for site components with functional or visual similarities. BEM demonstrates a great way to visually group chunks or blocks of information on a page so that you can begin breaking them down into modules. Header, body, footer, navigation, sub-navigation, utilities, callouts, calls-to-action… All components that I typically look for as candidates for CSS modules. You may also find that these same patterns repeat themselves on a micro-level within the components themselves.
For example, header-body-footer is a common visual pattern in page layouts. You may find that your callout boxes, asides, article abstracts, and so on include some or all of this pattern within their standard layouts. Keep this in mind as we move forward.
Authoring a Module
We’ve identified a module and are ready to start writing our styles. I usually do this as a three step process—Rough, Refactor, Repeat.
Roughing is the loose coding of the module in order to get it to look the way we want, like a rough sketch. I don’t concern myself with naming, as this often takes careful consideration and can impede progress. I also avoid too many decisions on modularity. I’d much rather get the presentation correct. The rest we’ll review when we refactor.
Refactoring is the clean up process of the code where I start making deeper considerations to optimize modularity. If the component is large, we may need to consider breaking it down into subcomponents*. We may also need to break our modules down into base modules and submodules*. Alternatively, we may need to separate into sibling modules*. These decisions should be made based on:
- Repeating styles within modules of similar function
- Reducing our dependency on HTML structure
- Keeping the relationship tight between styles and the thing receiving styles
The roughing and refactoring are steps that will repeat themselves throughout the process. It’s okay if our initial assumptions were incorrect. Refactoring as we go will help us see our mistakes and better optimize our CSS for scalability.
*Subcomponents are the parts of a larger whole. Like in the example above, a callout could be broken down into header, body, and footer. These are styled independently, but are intended to create an entire component.
*Submodules are the granular bits of a single module. They are dependent on a base module in order to achieve maximum effectiveness. They generally work as such:
- Base Module
- Provides the common, unifying styles for that collection of modules.
- Submodule 1
- Provides some granularity of styles for the variations within that collection.
- Submodule 2
- Provides even further granularity, catering to a more specific case.
I’ve stopped at 3 levels because I generally adhere to the Rule of Three. This should be sufficient to provide us with general styles, specific styles, and even more specific styles. Getting too specific runs the risk of losing modularity.
*Sibling Modules are functionally or semantically similar, but do not share the same values for common styles. They are independent modules that do not require a base module.
Naming a Module
Naming is probably more important than the styles themselves. This is nothing new to programmers. If you have some on your team, I would highly recommend talking with them. They can be a wonderful resource (especially if the practice OOP)!
We want the name to be page-agnostic—the module shouldn’t care about the page, it should only care about what it does. Functionality is a primary consideration when I name a module. If a module looks a certain way, it should be so for a reason. That reason should be indicated by what it does—Form Follows Function. So, what does it do? What is the purpose of this component? If it’s a callout, then that should probably be present in the name.
Something to consider is what our overall approach is going to be. Are we going to be semantic purists or presentational pragmatists? On the FAQ page of the OOCSS Wiki, Nicole Sullivan states
OOCSS can be written in a semantic or non-semantic way and, if you look at the framework, you will find class names that reflect both. For SMACSS, to
Increase the semantic value of a section of HTML and content is one of two core goals. However, Jonathan Snook himself says to
Accept that class names may describe a visual state, or in other words, be presentational. This will be something that you will have to make peace with as you work.
How we write the name of the module is part of the name we give it. SMACSS is largely a method of organizing your CSS, with naming conventions being a large part of what makes it work. In the case of modules and submodules, it is highly encouraged to include the name of the base module within the name of the submodule that extends it. For example:
Also, our naming convention may need to indicate an item that is a subcomponent of its larger whole. Let’s revisit the header-body-footer pattern on this one:
Here we’ve indicated that the callout module is broken up into a header, some body, and a footer. However, we have an issue with clarity—both the submodule and the subcomponent look the same! To compound this issue, we could also have a sibling module. Like:
These heading modules would all address different font-sizes. Between them, there are no common styles to modularize, so there is no base module.
To remedy the muddled class names, we may want to extend our convention with casing and special characters. BEM uses a very clear language made up of dashes, double-dashes, and underscores to clarify intent. You could also use camelCasing or character\escaping to extend your convention. Whatever you use, be sure it’s agreed upon by the team, it clarifies intent, and stays consistent.
This is Part I of Creating Modules. I tried my best to write this all in a single post, but soon realized that an understanding of the theory was just as important as the act itself. In Part II, we will create a sample module from a mockup, applying the theory we’ve discussed here.