Designing for Design Systems
Ideas for transitioning visual design into maintainable HTML & CSS
Design systems are really hard to build. They force designers into thinking about their designs in a more abstract way than they might be comfortable with. They force developers to codify design decisions that may or may not have been made with a system in mind. Design systems help with visual consistency and code reuse, but building the system itself comes with its own set of challenges.
This page is meant to serve as a guide to help designers and developers work together to build design systems.
"Design system" can mean a lot of different things to a lot of different people. When I refer to design systems, I'm talking about some combination of HTML, CSS, and documentation that exists to facilitate code reuse.
Start with high-level styles.
Designers should start design where they're comfortable. If they want to jump right in and start designing components, great. If they want to start by creating a comp for a whole page, cool. If they want to build a color palette based on the Fibonacci sequence or whatever, sure, that works too.
If you're building a design system, regardless of where the design starts, the development should start generally. Establish global styles and create reusable elements. The first code you write should be laying down solid foundations for the rest of your code to sit on top of.
Starting development with global styles is important because of CSS' cascading nature. As a stylesheet grows, changes to global styles become more difficult and risky. If you're familiar with ITCSS methodology, I'm referring to the upper parts of the inverted triangle.
Where to start
Get custom fonts in place. Add default styles for headings and paragraphs. Create a few classes for applying arbitrary font sizes. Maybe code up a way to prevent line lengths from getting uncomfortably long. Nearly any type of content can be represented as text, so it's worthwhile to make sure your foundation for typography is rock-solid.
Create some variables representing your site's brand colors. These variables can be used while building components to keep things consistent. Naming colors also helps with communication between designers and developers. "Midnight Blue" is easier to understand and remember than
Create styles for inline links. Whether they're the classic "blue & underlined" links or something more custom, your website will almost definitely use them. The web is basically just a bunch of pages linking to each other.
Create a set of classes to change the color and size of your buttons. Building a system early can keep you from rebuilding buttons in multiple places. This will help keep things visually consistent (good for users) and keep your code maintainable (good for you). If you ever need a special button for a special occasion, you can decide whether or not it should be part of this system based on how many styles it shares with existing buttons.
This is a relatively short list, and that's on purpose. A designer should be able to pair with a developer and create styles for these elements in a few sessions. Put HTML for all these elements on a single page, then go to town in your stylesheets.
The important thing here is to make a distinction between global and local styles. Build reusable elements so they can exist outside of a tightly art-directed context. Once you finish styling this small list of items, you've got yourself a solid toolkit for creating new pages within the browser. You can iterate smoothly. Hammer things out today; chisel things tomorrow.
Translate design decisions into guidelines.
Designers are very intentional in the decisions they make. This is what keeps websites consistent and understandable. These design decisions can be broken down into a what and a why:
What When a font is smaller than 16px, use all caps.
Why Because at small sizes, all caps is more readable.
What Make important things orange.
Why Because orange contrasts with all our other colors, and contrast draws attention.
What When performing an irreversible action, ask for confirmation.
Why Because this prevents user mistakes.
You can think of a website's design as a big collection of these decisions. Hundreds of these decisions need to be made to design something. Usually they're made while designing comps.
However, these decisions don't live inside of comps. Comps are only an expression of these decisions. They're an artifact based on a designer's intentions. Comps show a whole lot of what but very little why.
Where do these decisions live? Usually in the designer's brain. This isn't ideal. All that valuable knowledge and reasoning is effectively locked away; it has to be explicitly requested by anybody who isn't the designer. Designers tend to think the logic behind their decisions is obvious. It's not.
This problem can be remedied by writing down these design decisions and sharing them with the rest of the team. A design system is the perfect place to do this since it's the junction between design and development.
You can start by answering some high-level questions that are applicable to your entire site:
What typefaces are used? How do you decide which to use where?
How is color used? Do any colors have special meanings?
How is imagery used across your site? Are you using photos or illustrations? What kind of content should they show?
Writing these answers down—as opposed to implying them through comps—will give the rest of the team a useful peek inside the designer's mind. It leaves much more room to communicate the why of the design.
It's okay to start small and unorganized. Guidelines can grow as your design system grows. It's more important that designers are empowered to tweak this list as new needs arise and old needs grow stale. A good way to organize these guidelines will emerge naturally. Also, you may want to provide some of these guidelines directly on components. For example, you probably have multiple button colors. Which buttons should be used in which contexts?
Create a skin system.
Think about all the different background colors used across your website.
If you have code to start with, think of each instance of
background CSS properties in your codebase. Anything that contains text. Picture a few elements with those backgrounds applied.
Now think about what happens when you put a plain, unstyled link in those elements. Just drop an
<a href="#">asdf</a> in there.
Oof. Some of these are completely unreadable. This issue exists because the background colors we use tend to be baked right into components. Maybe links didn't need to exist in those components, so we never thought to design what they should look like. This is inflexible. It limits what our styles can do.
This isn't much of an issue for small-scale sites, but design systems should account for this flexibility even before it's needed. That means designers should think through this stuff before developers are forced to.
Designers can account for this by providing skins—sets of compatible colors—to developers. For each unique background color, create a set of colors to be used on top of it. Skins can start with a background color, a text color, and a link color. There may be other colors that are appropriate to include. Maybe an accent color to add some flavor? Or a lower-contrast, subtler color to help establish hierarchy? It depends on the content and needs of your design system.
The most important benefit of separating skins from components is that it creates a clear contract between design and development. Designers can focus on good-looking color combos. Developers can focus on implementing the concept of skins. People can focus on their specialties, yet everybody's speaking the same language. Treating this as a contained system also has maintainability benefits. New skins can be added. Existing skins can be modified. Contrast-based accessibility issues can be fixed in one place. Results can be verified on a single page. Maybe you could even enable designers to edit skins?
The hard part isn't designing for design systems. It's not implementing designs for design systems, either. The hard part is getting everybody on the same page. Working together as a unit. Understanding each other. Solving the people problems involving designers, developers, and everybody else involved. Good ideas get lost in the gap between these practices. Hopefully this guide gets you thinking about how to bridge that gap.