Scalable and Modular Architecture for CSS

Cover of the book Scalable and Modular Architecture for CSS (SMACSS) by Jonathan Snook

SMACSS by Jonathan Snook is referenced in numerous articles about on CSS and so I finally decided to read it. I can see now how the ideas in this book would have served as a seed for conventions like ITCSS and BEM.

Structured and organized CSS is easier to build on and maintain. Naming conventions improve clarity. Independence from HTML structure means that components can be moved around freely. A balance between class name only selectors, and nested selectors is key for maintainable CSS. Overall our goal should be to increase semantics and decrease reliance on specific HTML structure.

SMACSS attempts to achieve this by creating categories of elements and by creating some conventions on how to split and write your CSS. The author makes it clear that these are just guidelines and need to change as per the project and its realities.

Elements

Base

These are the defaults, usually element selectors, but could also include attribute, pseudo, child and sibling selectors. They don’t include any class or ID selectors. CSS resets are part of the base.

Layout

These divide the page into sections. ID or class selectors can be used for these, though class selectors are preferred and should have the l- prefix. If required, a combination of layout classes can be applied to a single element, for example l-stacked and l-flipped.

Layouts should only be concerned with laying things out in relation to each other. They shouldn’t care about the design of the modules, or the context in which they live. For example, an l-grid or an l-stack can exist in varied contexts.

Module

These are the reusable and discrete parts of the design. Use class selectors for these. Since they make up the bulk of the project they don’t have a prefix. Elements within the module shouldn’t be styled using their element selectors – for example, .card h1 is discouraged. This is because these selectors don’t hold any semantic information and rely on the HTML structure which is likely to change as the project grows. So, for elements inside the module use class selectors and add the base module name as a prefix.

While modules can sit inside layouts or other modules, they should be designed to exist as a standalone component. This ensures that they don’t break when moved around on the page.

When the same module is present in different sections, don’t use the parent selector to style the module differently. Instead, create a sub-class with the additional changes and include both classes in the HTML element:

<div class="pod pod-constrained">...</div>

State

These define how the modules and layouts will look in different states. Use class selectors for these, for example, – is-hidden or is-expanded. These are the only rules that are allowed to use !important, but only if they really need to.

Apart from state changes that happen by adding class names, elements can have different states based on pseudo classes like :hover or by using media queries. All states, including media queries should be defined alongside the module.

Theme

These describe how modules or layouts might look β€” fonts, icons, colors etc. Not used very often, but when they are they override modules, layouts and states.

Conventions

Files

The different CSS files can be broken down into the following:

  • Site settings
  • Mixins
  • Base
  • States
  • Layouts (one CSS file for each)
  • Modules (one CSS file for each)

These should be imported in the main CSS file in the above order.

Properties

Within a single CSS definition the properties should be ordered as follows:

  • Positon
  • Border
  • Background
  • Text
  • Everything else

Leave a Reply

Your email address will not be published. Required fields are marked *