CSS Architecture for Design Systems


Excellent post by Brad Frost in which he explains how they’ve combined class prefixes with BEM.

In addition to a global namespace, we added prefixes to each class to make it more apparent what job that class is doing. Here’s what class prefixes we landed on:

  • c- for UI components, such as .cn-c-card or .cn-c-header
  • l- for layout-related styles, such as .cn-l-grid__item or .cn-l--two-column
  • u- for utilities, such as .cn-u-margin-bottom-double or .cn-u-margin-bottom-double
  • is- and has- for specific states, such as .cn-is-active or .cn-is-disabled. These state-based classes would apply to
  • js- for targeting JavaScript-specific functionality, such as .js-modal-trigger. No styles are bound to these classes; they’re reserved for behavior only. For most cases, these js- classes would toggle state-based classes to an element.

An example selector would be .cn-c-btn--secondary, in which:

  • cn- is the global namespace for all styles coming from the design system.
  • c- is the category of class, which in this case c- means “component”
  • btn is the block name (“Block” being the “B” in BEM)
  • --secondary is a modifier, indicating a stylistic variation of the block (“Modifier” being the “M” in BEM)

CSS Architecture for Design Systems →

Published by Bramus!

Bramus is a frontend web developer from Belgium, working as a Chrome Developer Relations Engineer at Google. From the moment he discovered view-source at the age of 14 (way back in 1997), he fell in love with the web and has been tinkering with it ever since (more …)

Leave a comment

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.