Remember getting alphabet soup as a kid and trying to spell out your name? It was so hard because the letters were all jumbled up, stuck to the sides, or buried at the bottom. Sure, it could be done, but how long would it take? Imagine if the soup was on a plate with the letters in alphabetic order. You could quickly spell as many words as you’d like. Good CSS Architecture is just like that plate. We should strive to hand off our CSS on a plate; easy to find, easy to scale, and easy to reuse.
“…writing CSS is easy; looking after it is not.”
CSS is easy to write; right? Anyone can open up Chrome’s dev tools and start changing the font colors, padding, and margins. If it’s so easy to write, why do so many teams get it wrong? Important flags everywhere, selectors highly tied to the markup, and the same lines of code copy and pasted throughout the project. The reason why so many teams get it wrong is the lack of upfront planning around the UI and CSS Architecture.
What is CSS Architecture?
We’ve all been there, put on a new project, asked to make some small tweaks, and as we dig in to the CSS, find a messy, nested selector. We’re too afraid to change it so we slap on the !important flag. But how do we stop this cycle? The answer: CSS Architecture.
CSS Architecture is the methodologies and naming conventions your team sets out to follow to ensure the components you build will be scalable, reusable and easy to maintain into the future. Below are just a few options that each bring their own benefits.
SMACSS or Scalable and Modular Architecture for CSS was created in June of 2013 by Jonathan Snook. His book was the first of its kind and defined the idea of grouping your CSS selectors in five categories: Base, Layout, Module, State, and Theme. Base rules are the default styles that should be applied to HTML elements. Layout rules divide the page into sections, like a grid for example. Modules are those reusable parts of the design like callouts and sidebar sections. State rules are those that describe how modules or layout will look in a particular state. Finally, Theme rules describe cosmetically how a module may change when a given theme is applied. SMACSS is a great option for those starting a new project and want to get their feet wet with easy to find UI code.
ITCSS which stands for “Inverted Triangle CSS” is a methodology created by Harry Roberts that organizes a project’s styles as a layered upside-down triangle. ITCSS takes SMACSS to the next level by not only grouping styles but focusing on the order of importing styles to reduce inheritance and specificity issues for the entire document. It’s a model that allows the developer to manage the CSS in the most effective and least wasteful way. Here’s a breakdown of the layers:
Used in conjunction with a preprocessor like SASS, here’s how Harry defines the seven layers:
- Settings – Variables and settings
- Tools – Globally used mixins and functions.
- Generic – Reset and/or normalize styles, box-sizing definition, etc.
- Elements – Styling for bare HTML elements (like H1, A, etc.).
- Objects – Class-based selectors which define undecorated design patterns
- Components – Specific UI components.
- Trumps – Utilities and helper classes with ability to override anything above
While SMACSS and ITCSS are great options to organize your CSS, they don’t tell you how to write it. For that, we use Namespacing and BEM (Block, Element, Modifier).
What does this class do? What happens if I change this class? To solve these common global stylesheet questions, we prefix all classes to communicate the role and responsibilities of a class at a global level. Here are some common namespaces:
||Cosmetic free reusable patterns following OOCSS. Used in any number of unrelated places. Modify with caution as objects have a global reach on the site.
||Implementation specific piece of UI. Modular and reusable. Changes only affect the current context.
||Specific role not tied to a piece of UI. Padding, floats, clearfix etc.
||Change the cosmetic appearance of components under the scope of the theme.
||State or condition. For example, is-active on an anchor tag in the navigation.
||This class is intended for demo purposes only and should not be used in production
To learn more about namespaces, read Harry Roberts detailed blog post.
Created by the guys at Yandex, BEM communicates the roles and responsibilities of a class at the component level. It allows the UI Developer to avoid inheritance and provide a unique scope. BEM also states that each element should have its own class applied, thus keeping the specificity to a minimum level. Let’s take a look:
c-hero = Standalone entity that is meaningful on its own.
c-hero__blurb = A part of a block, noted by two underscores, that has no standalone meaning and is semantically tied to its block.
c-hero__blurb--primary = A flag, noted by two dashes, on a block or element. Used to change appearance or behavior.
Strive for a Plate
If you don’t plan how the interface will be built and maintained then you’ll be handing off a jumbled mess of letters in a bowl. If you architect your UI code using naming conventions like BEM and structuring your files following ITCSS, you’ll be handing off a plate. A plate to allow new team members to quickly ramp up. A plate for long term maintainability. A plate for smoother project handoffs.