June 14, 2021

What Is SMACSS and How Does It Work?

What Is SMACSS and How Does It Work?
This piece is part of a Learn HTML & CSS series. Check out part 4 here: What is OOCSS and How OCSS Works

SMACSS

Pronounced “smacks”, SMACSS stands for Scalable and Modular Architecture for CSS. The idea behind SMACSS is to break your CSS down into five distinct categories: base, layout, module, state, and theme.

Another distinct thing about SMACSS is that it advocates you to break your CSS down into five separate files so that the rules do not accidentally migrate into the different sections. This makes it easier to track down a specific piece of CSS based on its category.

Here are the category guidelines and what should go in them.

Base

These are your default values. They are things that are used to create consistency across your entire website such as padding, margin, border, and default typography settings.

Layout

The layout is based on structural and container elements such as the header, footer, articles, sidebars, asides, and columns. A common practice is to prefix your layout classes with l- . This is to let others know that this is a layout class and help keep track of where things are located.

Here are some examples of layout based CSS:

.l-full-width {
   width: 100%;
}

.l-half-width {
  width: 50%;
}

Modules

Modules are reusable parts that are repeated in some form on the page. These are things like widgets, menus, and form styling. Modules can be seen as complete ‘collections’ or ‘sets’ of visual elements that are grouped together in a certain format and are able to be reused in multiple places without breaking.

For example, you may have an .article class that defines the background color. You want to extend this .article module to include other elements within that particular group. You do this by adding a child element to it via and double dashed -- attachment.

.article {
   background: #000;
}

article--title {
  font-size: 2em;
}

article--text {
  font-size: 16px;
}

This is a good pattern because it lets you be descriptive and specific at the same time. For example, you might want to have a label on something but the CSS is different, depending on the context. When you follow SMACSS, writing modules often follow this pattern:

.object--description {}

Under SMACSS, you might end up with something like this:

.button--label {
  color: #000;
}

.card--label {
  color: #0F0;
}

This structure also helps avoid writing child and sibling selectors. Why is this important? Because once you start mixing and matching selectors based on their relationship to one another in the HTML, it means that your HTML is expected to be nested in a particular way. If you HTML is incorrect, then your CSS will not apply as expected. It can also lead to complicated rules over time.

Take a look at the example of the CSS below:

.label {
  color: #FFF;
}

.button .label {
   color:  #000;
}

.card .label {
   color: #0F0;
}

While the above looks simple enough, the relationship between .card and .label is not as strongly linked as using .card--label. It can also lead to issues in structuring HTML. Take a look at the example below:

<a href="" class="button label">Click me!</a>

This can also be written like so:

<a href="" class="button">
  <span class="label">Click me!</span>
</a>

They both create the same effect. However, there are more lines of code in the second example. For bigger snippets of code, the nesting can also lead to unnecessary complicated HTML structures. It also creates a dependency on having both classes in the right order. However, if you used button--label, there is no dependency or combination requirement. The HTML structure remains flat and keeps your code looking neat and clean.

State

State is used to describe how our modules look in different situations. This section of SMACSS is used to contain all the CSS rules that deal with interactivity.

The state classes don’t have to be attached to a specific object. Instead, they are often CSS rules that are used to define what happens after something has occurred. We don’t really get to see much of state in pure HTML and CSS pages. However, once you start throwing in JavaScript, separating out CSS state rules can help keep your code compartmentalized and easy to find.

This is because once you get to building a JavaScript application, your HTML and CSS will no longer be confined to just a single file. They are often split between multiple pages and various views.

For example, you might have some HTML code that looks like this:

<header id="header">
    <ul class="nav">
        <li class="nav--item is-selected">Home</li>
        <li class="nav--item">About</li>
    </ul>
</header>

nav--item is a module while is-selected is a state. nav--item is specific to the type of elements that it is intended to be used on, while is-selected can be used on other things like checkboxes, radio buttons, and other navigational areas within the page.

Theme

The theme is all the other additional decorative visual elements that make your webpage unique. This includes all your main colors, shapes, borders, shadows, and branding-related things.

The theme is the switchable part of your CSS and sits on top of your base. This means that if you discard the file completely, your base CSS and its implementation in the HTML will still continue to work — it just won’t have your specific branding.