This is the second part of Creating Modules. As previously mentioned, I have been abiding by the principles of SMACSS and OOCSS for a little over a year now. I wanted to share my process for creating a CSS module so that the learning curve might be shallower for any newcomers. In Part I, we covered a lot of theory. In Part II, we’ll go through the process with a mockup and write a module based off our analysis. Let’s get started!

Analysis

Our Design Mockup
Enlarge

Even though for this exercise we’re going to skip over the initial writing of the HTML, we’ll do a brief information analysis. Notice the overall structure of the information—the logo, the search bar, the nav, the content area with login box, the footer. Within the content area, we have a hierarchy established with a hero banner, headings, subheadings, copy text, and small print.

Based off of what we just reviewed, we start plugging in our base styles for the content using Normalize.css as a starting point (author’s preference). Because we were lucky and have access to the Photoshop file, we are able to go in and pull the exact font-sizes the designer used for the typography. Alternatively, you might have the designer accompany the PSDs with a README file containing info on font-sizes, color values, etc. This is where I believe it’s best to have the designer do the mockups and write the HTML/CSS—prevents things getting lost in translation.

Going back to the mockup, because we are writing in SMACSS, we can start visualizing some of our Layout Rules. Let’s look at our mockup and see some probable candidates for layout classes.

Our Design Mockup
Enlarge

You can see that we’ve mapped out considerations for .l-header, l.-navigation, .l-content, .l-footer.

Open to interpretation: You may also notice that I grouped the logo in with .l-header and not with .l-navigation (where it resides visually). This was a choice to give priority to semantic structure versus visual structure. One could argue that, since the logo acts as a giant “Home” button, it is acceptably part of the site’s navigation. Either would be fine, in my opinion.

Authoring the Module

We are going to jump ahead a bit in the process and fast forward past the writing of initial mark-up and Base Rules. Referring to our mockup, we have spotted a predictably repeatable element—the button. Notice that we have three variations, but they all are buttons nonetheless.

Repeatable Element: Buttons

Roughing

We can handle the roughing in one of two ways: as inline styles directly on the element or as on internal style sheet. Whichever you choose, I would highly recommend staying within that particular prototype. This helps isolate new styles to the page that requires them and aids in a quicker refactor. It also helps us to reinforce the idea of limiting the Depth of Applicability and clarifying Selector Intent.

But before we do any of that, let’s make note of some of the characteristics of our button. We notice it has rounded corners, a subtle gradient, a bit of an outline, maybe even a drop-shadow, there's more than double the padding on the left and right than on the top and bottom, and the font being used looks custom. We might jot these items down on some scratch paper so that we can mark them off as we start writing the CSS.

As far as the mark-up, let’s start with an actual <button>. We may need to use an <a> for other instances or, alternatively, we could use the <input type="submit" />. But for the purpose of demonstration, we’ll stick with the <button>.


<button class="button">Find It!</button>

I went ahead and gave it a class name of .button. Remember, we’re just roughing in the code to get the initial look down—don’t get hung up on the name just yet. For clarity of styles, I am writing the CSS in an internal style sheet.


.button {
  background-color: #015079;
  border-radius: 2px;
  border: 1px solid #296c8f;
  box-shadow: 1px 1px 1px 1px #013655;
  padding: 10px 20px;
}

I’m starting with the blue button here as it seems to be the standard button we’ll be using site-wide (note the search bar in the site header). This gives us the basic look of our standard button. Due to browser support issues and vendor prefixes, I intentionally skipped the background gradient. I also left out vendor prefixes for border-radius and box-shadow. Now on to typography…


/* Base Module */
.button {
  background-color: #015079;
  border-radius: 2px;
  border: 1px solid #296c8f;
  box-shadow: 0 0 1px 1px #013655;
  padding: 10px 20px;

  /* Typography */
  font-family:  sans-serif;
  color: #d5d5d5;
  font-size: 14px;
  text-transform: uppercase;
}

We mentioned earlier that the font looked custom. For now, we're just going to set up the basic expectation that it uses the san-serif font-family. We can go font searching later.

Now that we have our initial button looking close to the mockup, let’s look at some of the finer details. There are three buttons in the mockup: a "Find It" button, a "Join" button, and a "Login" button. All appear to be the same height. The "Login" and "Find It!" buttons are both blue, but the "Login" button is green. Everything else seems to be the same. So let's start a submodule based on the color difference.


/* Submodule */
.button-green {
  background-color: #45a641;
  border-color: #64b660;
  box-shadow: 1px 1px 1px 1px #013655;
}

Wait a second, did we just name that class “button-green”!? For now, yes. We’ll change the name after we refactor. So now, provided that we place our submodule below the base module in the source order, the color styles from .button-green will override our base modules styles for .button.

But does that feel right to you? Doesn’t that feel a bit like tying your shoe, then untying it only to tie it again? Yeah, it does to me to. So let’s refactor it!


Refactoring

I try my best not to create styles only to override them down the road. It feels much cleaner to be light-handed on the declarations and leave the base module open for extension. We’ve noted above that the major difference between the two button styles in the mockup is color. So, let’s remove any color declarations from the base module.


/* Base Module */
.button {
  border-radius: 2px;
  border: 1px solid;
  padding: 10px 20px;

  /* Typography */
  font-family: sans-serif;
  color: #d5d5d5;
  font-size: 14px;
  text-transform: uppercase;
}

/* Submodule */
.button-green {
  background-color: #45a641;
  border-color: #64b660;
  box-shadow: 1px 1px 1px 1px #013655;
}

The font color is the same in all three instances, so we are fine by leaving that in. Now let’s create another submodule with the color styles we just removed from the base.


/* Base Module */
.button {
  border-radius: 2px;
  border: 1px solid;
  padding: 10px 20px;

  /* Typography */
  font-family:  sans-serif;
  color: #d5d5d5;
  font-size: 14px;
  text-transform: uppercase;
}

/* Submodule 1 */
.button-blue {
  background-color: #015079;
  border-color: #296c8f;
  box-shadow: 1px 1px 1px 1px #013655;
}

/* Submodule 2 */
.button-green {
  background-color: #45a641;
  border-color: #64b660;
  box-shadow: 1px 1px 1px 1px #013655;
}

We now have a solid base module with to viable submodules to extend it. We can begin to focus more on the additional details. The custom font that we were suspicious of turned out to be Gill Sans Light. I’m sure that, at this point, we could find this exact typeface as a web font through a paid service, but for now we can use Sofia Pro Light from FontSpring (it’s free!). Also, if we wanted to go back and included declarations for a background gradient, this would be the time we would do it. Sense we offloaded our color to their respective submodules, all of the code necessary for cross-browser support won’t be such a maintenance bear.


The Whys

As a designer, it is always important for me to be able to answer the question “Why?”, so let’s take a look at some of the theory going on in our modules. We have our base module which carries the basic appearance of the button along with typography. We have separated the color into submodules. This is the beginning of the Single Responsibility Principle (SRP). If we say that one responsibility is form and a second is color, then we might be obliged to offload the typography to another submodule. This would be appropriate.

We may also consider the various instances of the button module within the interface. We may need a button that is taller or one that is shorter. For this, we might decide to pull out the padding declarations and abstract them further into additional submodules. SRP can help guide our abstractions by grouping them into responsibilities: color, typography, size, etc.

We can also see the rise of a basic principle of OOCSS—Separation of Structure and Skin. It is arguable that the border-style and border-radius, in this sense, would belong under skin. That would be worth consideration. However, in regards to the mockups we are working from, that is not an immediate requirement. Such a separation would not be currently beneficial to us, but we might keep it in mind.

Lastly, as we move forward, we will want to be mindful of the Open/Closed Principle (OCP). Meaning, once we’ve established our base class for the button module, we do not go back later and modify it—it is now closed. Rather, if we need to change some styles due to a new design pattern in the interface, the base module is open to extension by a submodule. This is also why I say to be light-handed with our early assumptions and only declare the styles needed to create that module.

Naming

We Roughed out and Refactored our module. At this point, we feel pretty certain there is nothing more we need to do with the styles. Now, let’s reconsider the names we have chosen. The -green and -blue of the .button submodules do not bother me because of dogmatic process (Separation of Concerns), but more because of practicality. I want to know why I am using the blue button and not the green one.

If we think in terms of function, the blue button (referring back to the mockup) is used for submitting a search and as a call to action to Join in the membership. So in place of -blue we could name -search and -calltoaction (or -cta). The green button is used for logging into the members area, so we could replace -green with -login.

While these names well describe the buttons’ function and offer more semantic value, they are not as reusable a we would like. Other than the text inside the blue buttons being different, they look exactly the same. This would mean repeating the styles unnecessarily to describe two seemingly different bits of functionality. Of course, we could gang up the submodule selectors like this:


.button-search,
.button-cta {
  background-color: #015079;
  border-color: #296c8f;
  box-shadow: 1px 1px 1px 1px #013655;
}

That’s better, but I still feel like we can reduce it even further to one class name. Plus, does blue look very call-to-actiony to you? So let’s dig a little deeper and abstract the submodule name a bit more.

Since the search bar is a permanent fixture in the site, we might say that blue is the button’s default appearance. So .button-default might work. We could also think in terms of hierarchy, in which case, .button-primary might be also appropriate.

The green button only has one instance within this particular page, but it could have other instances within differing contexts in future pages. With blue being the second most used color in our mockups next to grey, we can see that the green offers contrast and tends to stand out next to the blue. This has a very callout-like nature to it. Not to mention that the verbiage on the button itself is inviting a call-to-action. So, .button-cta may be functionally and presentationally more accurate here (the form of the button is definitely following its function). However, though we are unsure of the future uses of this button and that they will always be a call-to-action, we can be sure that the contrast between green and blue will remain, making .button-callout feels like a the better choice:


/* Base Module */
.button {
  border-radius: 2px;
  border-width: 1px;
  border-style: solid;
  padding: 10px 20px;


  /* Typography */
  font-family:  sans-serif;
  color: #d5d5d5;
  font-size: 14px;
  text-transform: uppercase;
}

/* Submodule 1 */
.button-default {
  background-color: #015079;
  border-color: #296c8f;
  box-shadow: 1px 1px 1px 1px #013655;
}

/* Submodule 2 */
.button-callout {
  background-color: #45a641;
  border-color: #64b660;
  box-shadow: 1px 1px 1px 1px #013655;
}

We might also consider reducing the .button to just .btn. I definitely share the OOCSS value of brevity in class names, so .btn would be the name I would personally go with.

Demo →

In regards to the submodules, consider the different possible contexts for the use of the button and choose the name that offers the most flexibility while still offering some meaning. If you hand these files off to another developer, assume that you will not be there to explain what that button does, so try to provide it within the name.

For now, I will skip the naming convention convention as I have not fallen firmly on a particular approach. I have been, on this site, experimenting with character entities (and escaping them) in order to extend the syntax of modular CSS. For further reading, I would suggest About HTML Semantics and Front-End Architecture by Nicolas Gallagher.

Conclusion

In Part I, we learned the theory behind the process of creating a module. Here in Part II, we’ve covered the practical application of the process. Through Analysis of the Page, Authoring a Module via Rough-Refactor-Repeat, and giving careful consideration to our Naming, we can create CSS modules with greater success. Mistakes will be made. When we make them, we will learn from them. All the while, we are on the road to writing better modular CSS.

Cheers!


Comments

comments powered by Disqus

← Back to Notes