0% found this document useful (0 votes)
185 views

CSS Architecture For Design Systems - Brad Frost

The document discusses the CSS architecture created for a large organization's design system. Key points: - The system needed to serve thousands of developers building over 500 apps across various technologies. - Principles for the CSS included modularity, legibility, clarity over succinctness, avoiding long selectors, and preventing conflicts. - A global namespace of ".cn-" was added to all classes to prevent conflicts. - Additional prefixes were used to indicate purpose: ".c-" for components, ".l-" for layout, ".u-" for utilities, etc. - State-based classes used ".is-" and ".has-" prefixes while ".js-" was reserved for JavaScript-specific functionality.

Uploaded by

jcovera
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
185 views

CSS Architecture For Design Systems - Brad Frost

The document discusses the CSS architecture created for a large organization's design system. Key points: - The system needed to serve thousands of developers building over 500 apps across various technologies. - Principles for the CSS included modularity, legibility, clarity over succinctness, avoiding long selectors, and preventing conflicts. - A global namespace of ".cn-" was added to all classes to prevent conflicts. - Additional prefixes were used to indicate purpose: ".c-" for components, ".l-" for layout, ".u-" for utilities, etc. - State-based classes used ".is-" and ".has-" prefixes while ".js-" was reserved for JavaScript-specific functionality.

Uploaded by

jcovera
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 21

2/18/2021 CSS Architecture for Design Systems | Brad Frost

my name is
brad frost

work
workshops
book
blog
contact

css architecture for


design systems
We just created a design system for a huge organization and established
a CSS architecture we’re quite pleased with. It’s one of the rst times I’ve
ever gotten to a project’s nish line without wishing I’d done at least a
few things di erently. So I thought it would be great to share how we
went about creating our system’s CSS architecture.

To give a bit of a context for the project, we were tasked with creating a
design system and style guide meant to serve the organization’s

https://bradfrost.com/blog/post/css-architecture-for-design-systems/ 1/21
2/18/2021 CSS Architecture for Design Systems | Brad Frost

thousands of developers, who employ a vast array of technologies to


build their over 500 internal web applications.

The overwhelming majority of the organization’s developers don’t


specialize in frontend development but rather focus on application
programming, data, and logic. Because these time-stretched developers
need to get their apps up and running quickly, they’d often simply copy
and paste frontend code from other applications or reach for frameworks
like Bootstrap to get the UI job done. As you might expect, the
cumulative result of these actions is a hodgepodge of incongruent web
experiences. Of course this is what we were aiming to remedy
by building the organization their own a thoughtful, robust UI design
system.

establish css principles


At the beginning of the project, we talked with developers about their
process and pain points, and asked how an interface design system
could make their lives easier.

We went through and completed my frontend guidelines questionnaire,


which resulted in a set of frontend principles that were to be
https://bradfrost.com/blog/post/css-architecture-for-design-systems/ 2/21
2/18/2021 CSS Architecture for Design Systems | Brad Frost

encapsulated within the system. Here are the CSS-speci c principles we


established:

Make it modular. – The design system is modular in every way,


which very much applies to the way CSS is written. There should
be clear separation between components.
Legibility is key. – Developers should be able to understand
CSS code at a glance and understand the purpose of any given
selector.
Clarity trumps succinctness – The design system may
sometimes seem verbose, but it delivers clarity and reslience in
exchange. Keeping CSS legible and scalable means sacri cing
a shorter syntax.
Keep things at – Long selector strings should be avoided
wherever possible in order to keep CSS as DOM-independent
and modular as possible.
Avoid con icts – Since components will be deployed to many
di erent applications, it’s critical to ensure that the design
system’s CSS doesn’t con ict with other libraries and systems.
This is accomplished by the system’s namespacing of class
names, described in more detail below.

https://bradfrost.com/blog/post/css-architecture-for-design-systems/ 3/21
2/18/2021 CSS Architecture for Design Systems | Brad Frost

From there, we established conventions and a syntax that embraced


these principles in order to meet developers’ needs. Here’s a look at the
class syntax we came up with:

global namespace
All classes associated with the design system are pre xed with a
global namespace, which is the Company Name followed by a
hyphen:

.cn-

If you’re working on a CSS architecture that is only meant to be served


to a single site or if you have a lot of control over your environment,
including a global namespace is likely unnecessary. But if your design
system is intermingling with other technologies, it might make sense to
create an identi er for system-speci c code. Lightning Design System
employs a similar approach for their system (with the pre x .slds-) as
third-party developers make use of their system in environments
Salesforce may not control. In our case, many of our client’s developers

https://bradfrost.com/blog/post/css-architecture-for-design-systems/ 4/21
2/18/2021 CSS Architecture for Design Systems | Brad Frost

use Angular so they’re already familiar with the notion of a namespace,


since Angular uses ng- as a namespace for Angular-speci c code.

class pre xes


In addition to a global namespace, we added pre xes to each class to
make it more apparent what job that class is doing. Here’s what class
pre xes 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 speci c states, such as .cn-is-active or .cn-is-


disabled. These state-based classes would apply to

js- for targeting JavaScript-speci c 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.
https://bradfrost.com/blog/post/css-architecture-for-design-systems/ 5/21
2/18/2021 CSS Architecture for Design Systems | Brad Frost

I was introduced to this concept by Harry Roberts, and while I thought


they made sense, I was a little skeptical at rst simply because it was
extra characters and I thought that the pre xes might actually decrease
code legibility. That wasn’t the case at all. After implementing the class
pre xes, we found them to be extremely helpful for clarifying the role of
each class and made it easy to decipher an application’s codebase at a
glance. This kind of clarity is especially helpful for the design system
users to be able to easily make heads or tails of things.

bem syntax
BEM stands for “Block Element Modi er”, which means:

Block is the primary component block, such as .cn-c-card or .cn-c-btn

Element is a child of the primary block, such as .cn-c-card__title

Modi er is a variation of a component style, such as .cn-c-alert--error

This methodology has been gaining a lot of popularity, and combining


these concepts with the global namespace and class pre xes allowed us
to create even more explicit, encapsulated class names.

https://bradfrost.com/blog/post/css-architecture-for-design-systems/ 6/21
2/18/2021 CSS Architecture for Design Systems | Brad Frost

putting it all together: anatomy of a class


The combination of a global namespace, category pre xes, and BEM
syntax results in an explicit (and yes, verbose) class string that allows
developers to deduce what job it plays in constructing the UI.

Let’s take a look at the following example:

.cn-c-btn--secondary

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 modi er, indicating a stylistic variation of the block


(“Modi er” being the “M” in BEM)

Here’s another example:

https://bradfrost.com/blog/post/css-architecture-for-design-systems/ 7/21
2/18/2021 CSS Architecture for Design Systems | Brad Frost

.cn-l-grid__item

cn- once again is the system’s global namespace.

l- is the category of class, which in this case l- means “layout”

grid is the block name

__item is an element, indicating that this is a child of the block


(“Element” being the “E” in BEM)

And one more:

.cn-c-primary-nav__submenu

cn- is the system’s global namespace.

c- is the category of class, which in this case c- means “component”

primary-nav is the block name

__submenu is an element, indicating that this is a child of the block


(“Element” being the “E” in BEM)
https://bradfrost.com/blog/post/css-architecture-for-design-systems/ 8/21
2/18/2021 CSS Architecture for Design Systems | Brad Frost

Again, there’s no doubt these classes are more verbose than most other
approaches out there, but for this speci c system these conventions
made a lot of sense.

other tricks
being explicit with minutia
In order to prevent things from falling apart we detailed how to handle a
lot of the minor details like comments, spacing around code blocks, tabs
vs spaces, etc. Thankfully, Harry Roberts has put together an excellent
and comprehensive resource called CSS Guidelines, which we used as
our baseline for these kinds of conventions. We combed through
everything and agged areas where we planned on deviating from what
Harry spelled out.

sass parent selectors


One issue I’ve always had with CSS is guring out where the hell to put a
given rule. If I have a a primary navigation component, but want to adjust
its alignment when it appears within a header component, do I put those
styles in my header or primary navigation Sass partial? Thankfully, Sass

https://bradfrost.com/blog/post/css-architecture-for-design-systems/ 9/21
2/18/2021 CSS Architecture for Design Systems | Brad Frost

parent selectors exist, which allows us to keep all component-speci c


styles under one roof:

.cn-c-primary-nav {
/**
* Nav appearing in header
* 1) Right-align navigation when it appears in the header
*/
.cn-c-header & {
margin-left: auto; /* 1 */
}
}

This means all my primary navigation styles can be found in the primary
navigation Sass partial, rather than splitting them between multiple les.

explicit rules around sass nesting


Nesting in Sass can be very convenient, but runs the risk of poor output
with overly long selector strings. We followed the Inception Rule and
never nested Sass more than three layers deep.

https://bradfrost.com/blog/post/css-architecture-for-design-systems/ 10/21
2/18/2021 CSS Architecture for Design Systems | Brad Frost

Keeping the design system’s CSS atness principle in mind, we wanted


to limit nesting to the following use cases:

. Modi ers of a style block

. Media queries

. Parent selectors

. States

1. style block modi ers

For modi ers, if the rule is only a few lines long, the modi er can be
nested inside the parent like so:

.cn-c-alert {
border: 1px solid gray;
color: gray;

/**
* Error Alert
*/
&--error {
border-color: red;

https://bradfrost.com/blog/post/css-architecture-for-design-systems/ 11/21
2/18/2021 CSS Architecture for Design Systems | Brad Frost

color: red;
}
}

Thanks to the & symbol, this would compile to:

.cn-c-alert {
border: 1px solid gray;
color: gray;
}

.cn-c-alert--error {
border-color: red;
color: red;
}

For longer style blocks we didn’t nest the modi er code as it reduced
the legibility of the code.

2. media queries

https://bradfrost.com/blog/post/css-architecture-for-design-systems/ 12/21
2/18/2021 CSS Architecture for Design Systems | Brad Frost

Component-speci c media queries should be nested inside the


component block.

.cn-c-primary-nav {
/* Base styles */

/**
* 1) On larger displays, convert to a horizontal list
*/
@media all and (min-width: 40em) {
display: flex;
}
}

This compiles to:

.cn-c-primary-nav {
/* Base styles */
}

@media all and (min-width: 40em) {


.cn-c-primary-nav {
display: flex;

https://bradfrost.com/blog/post/css-architecture-for-design-systems/ 13/21
2/18/2021 CSS Architecture for Design Systems | Brad Frost

}
}

3. parent selectors

The design system will make use of Sass’s parent selector mechanism.
This allows all rules for a given component to be maintained in one
location.

.cn-c-primary-nav {
/**
* Nav appearing in header
* 1) Right-align navigation when it appears in the header
*/
.cn-c-header & {
margin-left: auto; /* 1 */
}
}

This will compile to:

.cn-c-header .cn-c-primary-nav {
display: flex;
https://bradfrost.com/blog/post/css-architecture-for-design-systems/ 14/21
2/18/2021 CSS Architecture for Design Systems | Brad Frost

All styles for cn-c-primary-nav should be found in one place, rather than
scattered throughout multiple partial les.

4. states

States of a component should be included as a nested element. This


includes hover, focus, and active states:

.cn-c-btn {
background: blue;

&:hover, &:focus {
background: red;
}
}

This will compile to:

.cn-c-btn {
background: blue;

https://bradfrost.com/blog/post/css-architecture-for-design-systems/ 15/21
2/18/2021 CSS Architecture for Design Systems | Brad Frost

.cn-c-btn:hover, .cn-c-btn:focus {
background: red;
}

States can also take the form of utility classes, such as is- and has-:

.cn-c-accordion__panel {
overflow: hidden;
max-height: 0;

&.cn-is-active {
max-height: 40em;
}
}

This will compile to:

.cn-c-accordion__panel {
overflow: hidden;
max-height: 0;

https://bradfrost.com/blog/post/css-architecture-for-design-systems/ 16/21
2/18/2021 CSS Architecture for Design Systems | Brad Frost

.cn-c-accordion__panel.cn-is-active {
max-height: 40em;
}

Putting these rules in place gave us some constraints and conventions


we needed to adhere to in order to create a solid system. When we ran
into instances where a convention wasn’t obvious or a solution could be
handled in a few di erent ways, we’d have a conversation about how to
handle it and update the guidelines if needed.

does this work for everybody?


Before you get all hot and bothered and start disagreeing with the
speci c decisions we made in creating our system, recognize that this
architecture made sense for the system we were working on. Does this
mean it’s a bulletproof solution for every project? No, and I’m not
proposing that. The speci c needs and setup of the organization should
very much in uence your design system’s CSS architecture.

https://bradfrost.com/blog/post/css-architecture-for-design-systems/ 17/21
2/18/2021 CSS Architecture for Design Systems | Brad Frost

I work on plenty of projects where I can get by with strings like .table-
of-contents li a, but those projects are mostly managed by me. For
client projects that involve working in a team environment, I’m very much
gravitating towards more verbose, explicit syntaxes like I described
above because they provide less room for people to screw things up. It’s
great to see other teams like Sparkbox come to similar conclusions.

After a few weeks away from the project, we’re returning to continue
work on version 1.1 of the design system. I’m looking forward to coming
back to this code base and seeing how quickly I can get re-acclimated
with it!

Posted by Brad Frost on 07 Nov, 2016


Tags: architecture, css, design systems

hey there!
I'm Brad Frost, a web designer, speaker,
consultant, writer, and musician located in
beautiful Pittsburgh, PA.

https://bradfrost.com/blog/post/css-architecture-for-design-systems/ d 18/21
2/18/2021 CSS Architecture for Design Systems | Brad Frost

atomic design
I wrote a book called Atomic Design,
which covers all that goes into creating
and maintaining e ective design
systems. You can read it online and
order the ebook.

workshops & training


I educate organizations about design systems, atomic
design responsive design strategy and more I love
https://bradfrost.com/blog/post/css-architecture-for-design-systems/ 19/21
2/18/2021 CSS Architecture for Design Systems | Brad Frost
design, responsive design, strategy, and more. I love
helping teams understand the concepts, techniques, and
tools used to create successful design systems and
establish more collaborative work ows. If you're
interested in having me in to give a one or multi-day
workshop at your company, get in touch!

consulting frontend design


I help organizations create successful design systems and I write HTML, CSS, and presentational JavaScript, and I
bring great web projects to life. From strategic guidance aim to create experiences that look and function
to in-the-weeds design and dev work, I can be as hands- beautifully across anything that can access the web. If you
on or hands-o as needed to ensure your project is a have a project that could use my frontend help, please
success. feel free to reach out.
https://bradfrost.com/blog/post/css-architecture-for-design-systems/ 20/21
2/18/2021 CSS Architecture for Design Systems | Brad Frost

writing side projects & collaborations


I write about web design best practices, design systems, I've had the opportunity to collaborate with some amazing
responsive design, and other tasty topics on my blog. I people to create tools and resources for web designers,
also enjoy sharing and commenting on interesting links including Pattern Lab, Styleguides.io, This Is Responsive,
from around the web. Death to Bullshit, & more.

contact music
Interested in having me conduct a workshop at your I play music with my wife and brother in our home studio.
company? Have a project that could use some consulting Nothing serious; I just love playing music.
or frontend help? Have a question? Get in touch!

around the web


You can follow along on Twitter, Facebook, Instagram,
Github, Codepen, LinkedIn, Spotify, Last.fm, and Noti.st

https://bradfrost.com/blog/post/css-architecture-for-design-systems/ 21/21

You might also like