Turning a design library into an accessible code-aligned design system

Rajesh shares practical lessons about auditing and redesigning design systems.

An illustration of a hand holding a beaker of water, with some cogs on a blue background.

What’s the difference between a design library and a design system?

A design library is a collection of design assets that enable Designers and Developers to build a consistent design language across a product or suite of experiences. A design system is a framework including, but not limited to, design decisions (design tokens), an atomic component library, comprehensive documentation, a contribution model and ongoing activities to ensure continuous adoption.

The purpose of a design system is not just to build a consistent design language but also to align all stakeholders, reduce design and development efforts and adapt to new product needs and wants.

How do you know if you’ve got problems in your design system?

If you’ve picked up a design system before, you’ll know when things aren’t right. The colours may not be accessible, the naming conventions may not be obvious and the component logic may not match the HTML structure. Even if it’s your first time working on the design system, your first step is the same:

Start by auditing everything

Take a good look at what you've got, compare it to industry standards and trust your design system expertise. Make a list of the complex and/or confusing bits that need fixing.

How to frame and present problems and get buy-in from the team to fix the design system

Once you've identified the accessibility issues with colours and typography and listed down heuristic concerns around components and patterns based on best practices, it's time to get your problem-solving cap on.

Write down why something's not working, what could go wrong if you ignore it and how it could work better. Then, present these findings to your team. Explain why things need fixing in terms of the potential impact they could have going forward and show them how other design systems are approaching these challenges while suggesting solutions to the problems you face.

Now, here's the catch, not all problems you’ve identified will get the green light for fixing. It might be because your team isn't aligned or that time is against you. But don't fret! Organise your solutions into phases. Yes, it’s additional work on your end, but it keeps the team aligned and the project does not need to be stopped which creates a blocker for cross-functional teams.

What challenges will you face while doing the actual work?

You’ll be jumping from system thinking to product thinking. The team on the other hand will expect dev-ready components at the end of each sprint, while you will be concerned about accessibility, reusability and whether these elements are best in class or if alternatives should be explored to offer a better user experience.

Keeping the documentation up-to-date will be a challenge, client feedback and technical feasibility will require going back and revising your new and improved components and their usage guidelines.

Moreover, you’re a human and you’ll make mistakes, one of the challenges will be to fix your own mistakes as a system thinker. Maybe you missed something, or a property you defined is overkill, or you want to revise the naming of a shipped component. But, don’t panic! Once you’ve identified that mistake solve it collaboratively. Do not try to solve it in isolation. This will enable you to reach an elegant solution that everyone agrees on. Then it’s just a change log.

Trust me, all this hard work pays off when you see Designers whipping up templates in minutes, configuring components in seconds and finding what they need in the blink of an eye.

Practical lessons from auditing and redesigning a mid-size design system

Try to avoid multi-layered nesting

In theory, you would expect a design system to work flawlessly when you nest atoms into molecules, molecules into organisms and organisms into templates. However, design tools such as Figma don’t work as flawlessly as HTML and CSS.

When designing components, plan their logic and structure as closely as possible to HTML’s structure. But do not try to force replicate it within Figma by using atoms that have nested atoms inside.

For example, choosing a class from a long list of prescheduled classes would need a radio choice list with date time, location, price and discount info. All these radio choices may be individual atoms in your design system, but you should feel free to detach atoms to use within advanced radio choices to surface the intended properties and avoid multi-layered nesting issues in Figma.

Know when to standardise and when to specify

Not everything needs to be abstracted into one almighty solution used across every use case. This simply doesn’t work. Be liberal about creating variants for specific use cases. I’ve even created a whole set of sibling components that look and behave similarly but are separate in Figma. It makes designers' lives easier when the component is faster to use and even faster to build and test.

For example, you may have a standard card component with an Image, Heading, Body and a CTA, which also has variants for platforms and states. It makes sense to use the card as a base component and then use instances for all types of use cases. But what if, you instead create a Highlight Card to highlight any type of content, an Article Card which only has structure and properties applicable to long-form content, or a Feature Card that has a much more prominent visual treatment than the rest of the cards?

Go for it, be liberal with sibling components. Your Feature Designer will find them quickly in the Assets panel and know when to use which sibling, your Content Writers won’t worry about using the wrong component or variant, and your Developers will build and test only the logic, structure and properties relevant to that component.

Surface critical documentation on the variant level

If a card heading has a set character limit and looks similar to another card then surface that info as a dummy copy in the heading.

“[card-name] with [character limit]”

When your cross-functional team including feature Designers, Content Writers and Front-end Developers look at those components they can read the name of the component and what the applicable constraints are, just by looking at them.

Remember, people only read documentation when they absolutely have to, most of the time they go with intuition. That’s why it’s important to surface information/guidelines that are vital to that component and its use as part of each variant.

Use the slot technique carefully

If you have a carousel use a slot or placeholder component but set “preferred values” to prevent its abuse. Be sure not to overuse slots and don’t nest components that already have slots in them because this will create multi-layered nesting that can frustrate Designers for two reasons:

  1. They have to tap multiple times to find the right component to configure.

  2. If you expose all nested components then the property panel looks like a long, complicated, list of toggles and dropdowns that has to be used just to find and configure a simple nested component.

Slots are great when used sparingly. However, they should be avoided in modals and content grids, where Designers need to place multiple components.

Child components

If a component seems like a good solution within a template but not in other areas of the product don’t try to force standardising it. Keep those components as child components of that template. This will mean Designers as well as Developers only view them as part of that template rather than something to be reused across the product.

However, in the future, if you find that a child component has grown up and can be reused elsewhere, you should consider extracting it from the template and offering it a separate seat on the component library, with the proper documentation.

The result of aligning a design system

After months of hard work, we have a colour and typography system adhering to WCAG AA standards, a component library that follows principles of heuristics as well as patterns and flows that are insight-driven.

Improving a design system doesn’t stop there

The journey we’ve been on so far is just the beginning, once you start shipping components and templates you need to keep doing the following to ensure it turns into a living, breathing, design system:

Design QA

Plan the format, frequency and resources for this with your Project Team. The goal is to audit everything you’ve designed again but now in code. This includes the theme CSS file containing colour and typography values, component props and CSS classes. Test the staging version on popular browsers and raise bugs, write acceptance criteria and approve tickets when they are fixed to help guarantee the quality of design in code.

Design surgery

Have friendly open sessions with the developers who are coding components. This will help you to prevent design bugs and suggest better alternatives for writing class names and structuring properties in code.

Publish

Ideally, you should export everything into a cloud-based environment such as Storybook or ZeroHeight, or even more modern solutions such as Supernova or Knapsack. Publish all of your components there along with documentation, and ask Front-end Developers to upload a coded version of each component with all properties exposed. This is so everyone in the extended team can access the system. You can then set role-based access to consume components and updates.

This will provide one single source of truth to all. Importantly, this will be accessible via browsers with no NPM install needed to analyse how the component is coded or Figma know-how to view the component. Every person in the team right across the technology spectrum, from the Project Manager to the Software Tester, will be able to see the latest public version of the design system.

Handover

Finally, make it easy for new Designers and Developers to onboard. If you’ve written comprehensive documentation then you’ve already done your job. But, consider setting up workshops and recording introductory videos on template files and component files so new people in the team get up to speed in no time.

Hopefully, you’ve enjoyed my thoughts on shifting a design library to being a living breathing design system, available for all consumers and used to create better digital experiences.

Related articles