This article is part of a series created in partnership with SiteGround. Thank you for supporting the partners who make SitePoint possible.
In this article, I’m going to discuss three successful approaches to CSS architecture, their principles, goals and advantages.
Why Can CSS Code Spiral Out of Control?
Keeping CSS code lean, re-usable and maintainable is notoriously hard. If you neglect to enforce any coding and organizational rules in a consistent way, this can be the case both for small and medium to big projects, where more than one developer is at work.
Where the codebase is large, goes through a number of changes over time, and organization is lacking, it often happens that teams prefer to add new style rules at the end of the style sheet document rather than remove chunks of it or modify what’s already there. The main reason is often that the effects of editing or removing CSS declarations can be unpredictable and risk breaking the design somewhere in the project. This is a losing strategy, which can lead to code duplication, specificity issues where overriding style rules turns into a battle, and overall bloat.
Most often than not, choosing the methodology that most suits your needs is an iterative process, which starts with getting familiar with what’s already out there.
Here are three methodological approaches to help you fight the challenges of a messy style sheet.
The goal of the BEM methodology is
to develop sites which should be launched fast and supported for a long time. It helps to create extendable and reusable interface components.
The key concepts here are easy project maintenance over time, and components reusability.
The core BEM strategy consists in organizing CSS code into reusable modules with the help of a smart naming convention. Let’s have a closer look.
What Is a Block?
Identifying blocks is a crucial step of applying the BEM methodology. A block is a
functionally independent page component that can be reused. In HTML, blocks are represented by the class attribute.
When deciding what to consider a block, ask yourself if you can easily remove that portion of code and use it somewhere else. For instance, you can consider a website header or footer to be a block.
You can safely nest blocks, for instance, you can place a menu block inside a header block.
<header> <ul class="menu"> <!-- menu items here --> </ul> </header>
Learn PHP for free!
Make the leap into server-side programming with a comprehensive cover of PHP & MySQL.
RRP $11.95 Yours absolutely free
Because in principle you should be able to reuse blocks anywhere in your page, your CSS for the block should not set any margins or positioning rules.
Finally, when choosing a name, make sure the name describes what the block is for, what its purpose is, never what its appearance or state is. In other words, its name should answer the question: What is it? (e.g., a header, a menu, etc.), not What does it look like? (e.g., fixed header, small menu, etc.).
What Is an Element?
According to the BEM methodology, an Element is
A part of a block that has no standalone meaning and is semantically tied to its block.
Here are a few principles applying to elements:
- Elements only live inside a block
- Elements cannot belong to other elements, they can only be part of a block
- You can build nested elements
- Element names describe their purpose, not their appearance
- When naming elements, you need to follow this conventions:
What Is a Modifier?
A Modifier is
An entity that defines the appearance, state, or behavior of a block or element.
For instance, a header block can be fixed to the top of the page, an accordion block can be open or closed, a button block can be disabled, etc.
The BEM naming convention for modifiers looks like this:
Pros of Using BEM
These are some advantages of using BEM in your projects
- New developers can quickly understand the relationship between a component in markup and CSS rules
- It facilitates productivity in teams. The benefit is especially noticeable when working on larger projects
- The naming convention reduces the risks of class name collisions and style leaks
- CSS is not closely tied to the markup in a specific location inside the page
- CSS is highly reusable
Scalable and Modular Architecture for CSS, or SMACSS, is a web development methodology for organizing and writing CSS code. Its creator, Jonathan Snook, describes it as follows:
SMACSS is a way to examine your design process and as a way to fit those rigid frameworks into a flexible thought process. It is an attempt to document a consistent approach to site development when using CSS.
At its core is a way of categorizing CSS rules. Categorization brings forth patterns, i.e., things you see repeated more than once in the design, around which you can work out guidelines for coding maintainable and reusable CSS.
SMACSS core categories are:
- Base — In this category belong CSS rules that govern the default appearance of elements. Selectors include single element selectors, attribute selectors, pseudo-class selectors, sibling selectors, etc. For instance,
a, a:hover, etc.
- Layout — This category is for styles used to divide the page into sections.
- Module — Modules are the reusable lego-like parts of the design, e.g., menu, dialog, search box, etc.
- State — This category includes styles to describe what the layout or modules look like when in a particular state (e.g., visible or hidden, expanded or closed, etc.) or in a particular view (e.g., Home page or inner page)
- Theme — this category is similar to State in so far as it includes CSS rules that take care of layouts’ and modules’ appearance. Not all projects need this extra category, but it’s good to know it’s there.
SMACSS Naming Convention
Related to the categories outlined above, SMACSS proposes a naming convention to help with code organization and dev teams productivity.
Layout, State and Module rules are prefixed with a meaningful name or abbreviation.
For Layout rules, something like
grid-, or even simply
l- are acceptable prefixes.
For State rules, the convention is to prefix the state with
As for Modules, just use the name of the component you’re building, e.g.,
For instance, to style an open dialog box, you can use a selector like
.dialog.is-open in your CSS. Related elements inside a module, as well as variations of the same module, should use the module’s base name as a prefix. Also, try not to use Ids, element selectors, or nested selectors. For instance, to select a menu item inside a module called menu, instead of writing your selector like this:
.menu li a, use something like this:
Unlike BEM, SMACSS doesn’t prescribe an overly-strict naming convention. Jonathan Snook makes this clear as he claims:
… don’t feel like you have to stick to these guidelines rigidly. Have a convention, document it, and stick to it.
Advantages of Using SMACSS
Some advantages of the SMACSS approach to CSS coding are:
- It offers valid guidelines for modular, maintainable CSS while avoiding to be overly-prescriptive
- You can learn (and teach) SMACSS quickly
- SMACSS naming convention is less verbose and in some ways easier to come to grips with than BEM’s
- It’s flexible enough to work well for both large and small projects
Enduring CSS or eCSS is
A guide to writing style sheets for large scale, rapidly changing, long-lived web projects.
This CSS methodology has really piqued my interest for the original perspective taken by its author, Ben Frain, on the challenge of dealing with CSS at scale.
A central concept of eCSS is isolation. Isolation means that each component is an insulated unit of code with no dependency, no contextual baggage, reusable and removable without risk of causing style leaks.
This is achieved mainly by
- Encapsulating all the code, not just CSS, but all the technologies you need to build each component, in its own shared folders.
- Creating a brand new component each time you need a component similar to one already in place, but with some variations, even if the variations are slight.
- Using a strict CSS naming convention
On the basis of the second point above, it seems clear that repeating properties and values are not a problem for eCSS. In this regard, eCSS represents a radical departure from methodologies like BEM and SMACSS, which extend or abstract from the existing component thereby avoiding, or trying as best they can to avoid, code repetition.
Does this mean eCSS produces heavy style sheet files? Not necessarily. After some tests using file compression, Ben Frain came to the conclusion that, due to the fact that ‘gzip is incredibly efficient at compressing repetitive strings’, the difference in terms of file size between using eCSS and other methodologies that favor abstraction over repetition were super tiny.
Benefits of Using eCSS
Here’s what you can gain from applying the eCSS methodology and embracing its view of repetition:
- By keeping each visual pattern isolated, the CSS code becomes easier to maintain
- Although you find repeated properties and values, file size increases remain minimal in the long run. This is so because modules are self-contained, isolated units that you can quickly remove when you don’t need them anymore, without fear of breaking the design
- All language/technology files necessary to create a module share the same folder, making both editing and physically removing what’s no longer needed, extremely easy.
You can read all the details of this innovative methodology in Frain’s book Enduring CSS.
Writing maintainable and well organized CSS code has its challenges. In this article I’ve presented three methodologies that can help with the task. It’s by no means an exhaustive list and none of these approaches solves all the problems you might come across while working on a project.
Just try them out and see what works for you. You can also try using BEM and SMACSS together, or even work out your own methodology on the basis of the specific set of problems you set yourself to solve.
What are your golden rules for writing organized, manageable CSS code? Do you think using a methodology for CSS architecture can ease the pain? Hit the comment box to let me know.
Maria Antonietta Perna is co-Editor of the HTML/CSS Channel at SitePoint and a front-end web developer. She enjoys tinkering with cool CSS standards and is curious about teaching approaches to front-end code. When not coding for the web or not writing for the web, she enjoys philosophy books, long walks and good food.
Jump Start Git, 2nd Edition
Visual Studio Code: End-to-End Editing and Debugging Tools for Web Developers