For a design system to truly be integrated and applied to an application, it needs to live in the codebase as much as it lives in the design software. Thankfully, we have lots of tools—like Figma, Storybook and the Kendo UI component library—to help us bridge that gap and make sure we’re keeping things in sync.
In the previous post in this blog series, we discussed the first steps for implementing the groundwork of a successful design system: choosing a library, setting up our global CSS file and defining our design tokens to coordinate with the design team. Now, let’s talk about using those smaller pieces to build larger, reusable components.
What good are all those design tokens if we don’t start applying them to components, right? Ideally, the bulk of our design system implementation is done via these tokens in the form of variables that get used in the styling of the components that we build. That means that our component-scoped styles will look something like this, with the majority of the styles being imported and applied from the global CSS using the design tokens and only a few specific, unique values set manually:
.card {
border-radius: $borderRadius;
background-color: $primaryBG;
border: $border;
filter: $dropShadow;
padding: $basePadding;
max-width: 50%;
}
The component library is the part of a design system that developers are usually most familiar with already, so we won’t spend too much time here. For anyone who’s interested in a deeper dive on creating their own component library, check out this earlier series by TJ that breaks it down into some excellent, actionable steps. Not to mention, there are some fantastic tools out there, like Storybook, that offer tons of resources to make component library creation, maintenance and testing a breeze.
Instead, let’s talk about some more specific aspects of component library maintenance in relation to their position within a larger design system: coordinating with designers and building pattern libraries and templates with our components.
One of the most effective ways for developers and designers to stay in sync on component design and functionality is via Figma UI kits. A good Figma kit will include a breakdown of every single component in a library, including all design tokens and various interaction states for each component. We’re already familiar with all the ways in which a component library can be beneficial for developers: they help build in accessibility, speed up development time, offer UI and interaction pattern consistency for users, etc. With a Figma kit, designers can enjoy the benefits of all those things as well—with a few additional perks!
Developers are often most comfortable working directly in code, but designers spend most of their days working in design software. For a design system to work, we need to eliminate the barriers of access that make it harder or less intuitive to use—that means that nobody should have to learn an entirely new set of skills in order to use the design system. Designers should be able to work where they prefer to work, as should developers.
By offering an exact, one-to-one replica of the component library in the workspace that designers are most comfortable with, they’re able to take a deep dive into the components from a design perspective. This not only enhances a designer’s understanding of the components and how they function, it also makes it much easier for them to adjust the style of the components to match the design system because they can see all the components in one place.
Often, component library documentation splits up each component, allowing developers to focus in on the details of each one individually. While that makes sense for a development approach, designers more often need a birds-eye view, allowing them to see and understand how all the components look together within the shared design system styles.
With Figma kits, designers are empowered to do things like adjust design tokens and know exactly how that will map to the variables on the development side, communicate complex user interface ideas to developers via pixel-perfect mockups (and offer those mockups for developers to inspect with the Figma Dev Mode), and create new page or feature prototypes for early-stage user testing—just to name a few.
Designers can maintain the design system core files in Figma and share them with the development team via export tools. For example, the Kendo UI Figma Kit design tokens can be imported into ThemeBuilder Pro via the ThemeBuilder Figma plugin. This allows for easy translation of the design system from Figma into CSS.
Then whenever the design team needs to make an update to a design token, they can do so in Figma and just let the development team know—when the dev team re-imports the variables, it will automatically update any components those tokens were applied to in ThemeBuilder. The dev team can then simply re-export the ThemeBuilder CSS, replace the global CSS file in their app and see the design team’s updates applied across the entire component library—just like that! There’s no easier way to keep a component library in sync.
Once we have a component library with our design system styles applied, it’s time to start putting those lego pieces together into reusable chunks. Many applications and websites reuse more than just individual components—those components most often get combined to create specific interaction patterns that repeat throughout the interface. This approach is generally based on Brad Frost’s Atomic Design approach (which, if you haven’t read, you absolutely should).
For example, maybe we repeat a pattern of components along the bottom of several different types of articles on our website: a specific layout of the author photo and information, cards with other suggested/related articles and icon buttons for sharing on social. The pages for these articles might not always look the same, but that section at the bottom is consistent. That’s a pattern that we can capture and reuse in the same way that we do with the individual components themselves.
Image from https://atomicdesign.bradfrost.com/chapter-2/
In general, we want to think of these as separate to components, because they tend to be larger and more complex. The line between what constitutes a complex component vs. what constitutes a pattern can be fuzzy and is ultimately left up to the discretion of the developers and designers building the design system.
Personally, I think of components as elements with one specific goal, whereas patterns could have several. For example, I would consider a text input + button lockup to be a component since there’s only one thing a user can do with it (submit text). However, I would consider the previously described article footer lockup to be a pattern, since the user could click on a related article, contact the author or share the article on social. Once again, though, this is not a hard and fast rule—just my personal approach to building and organizing design systems. Ultimately, the only important part is that the entire team understands and agrees upon a single definition.
A page template, on the other hand, is much clearer—it’s a reusable layout of components and patterns for an entire page. These are especially useful for websites or applications that have many pages that will need to be visually similar but offer different content: documentation libraries, blogs, store product pages, and similar. While the content of those pages might not always be exactly the same, a template will ensure visual consistency across them all.
For example, a product page might not always have the same number of photos, the same length of description, the same number of product options, etc., but we still need all product pages to look cohesive. By creating a template, we can accommodate the most basic and extreme situations—and save ourselves the time and energy of recreating work/re-solving problems.
Image from https://atomicdesign.bradfrost.com/chapter-2/
Perhaps one of the greatest benefits of using a pre-made component library is being able to leverage the expertise of a whole team, without having to hire a whole team. This really shines in the world of accessibility, where not everyone feels completely comfortable or considers themselves an expert—and yet, creating an accessible application or website is truly non-negotiable.
While using a third-party component library doesn’t let you completely off the hook on accessibility testing, it does greatly reduce the workload. It’s both reassuring and a time-saver to not having to worry about doing this yourself, because someone else has put in the time and research to craft an accessible experience for your users. When you’re building with accessible core components, a lot of the accessibility work happens “for free.”
That being said, there’s more to a design system than just the components. When choosing colors for design tokens or various UI elements, it’s important to make sure they meet an accessible standard for color contrast. The WCAG (Web Content Accessibility Guidelines) defines three levels of color contrast ratios—failing, AA and AAA. AA level means the colors have enough contrast to be readable, but might still present problems for some users. AAA level means that we have achieved extremely high contrast that should be readable for the vast majority of our users. We should always aim for AAA compliance, but making sure we’re not failing is the bare minimum.
Another important aspect of accessibility and color is ensuring that we’re not communicating any information through color alone. This is a dangerously easy trap to fall into, unfortunately—especially with things like forms, data visualization and confirmation/cancellation dialogs. Make sure to review the components, patterns and templates with the design system styles applied to confirm that there’s always an icon or text supporting any color-coding.
When it comes to making accessible layouts and interactive UI elements, it’s good to leave some—literal—room for error. When buttons and other “click zones” are too small, they can be difficult to accurately target and interact with. We want to ensure that the padding we define for input fields, buttons, icons and more all make them take up enough visual space that the user isn’t working with a prohibitively small target.
Finally, consider the text styles. Setting a large enough text size is step one—16 pixels is the standard recommendation size for body copy. More important than the default size, though, is how users can adjust it. Having a built-in text adjustment in your settings is a nice touch, since that will allow a user to increase the size of the font without affecting the other elements on the page … but, since that’s rare, we also have to think about what happens when a user increases the zoom on the page via the browser tools. If zooming in breaks our components, patterns or templates, then it’s back to the drawing board.
Thankfully, Storybook has a bunch of great add-ons that will make accessibility a natural part of design system implementation and component design. I highly recommend
addon-a11y
. It’s probably the most popular and beloved Storybook accessibility add-on—and for
good reason! It’s packed with great features, and it runs on the well-known Axe Accessibility Engine.
The Accessibility panel that this component adds is one of the best and easiest ways to test as we work in Storybook. Each time the component loads, it will check it against the WCAG, and we can make the changes while still in the build phase, rather than finishing a component completely and then having to go back and try to retrospectively make it accessible. Each violation that appears will have a “more info” link to the WCAG website, where we can learn more about the guideline that your component hasn’t met, and how to fix it.
The vision simulators are also incredibly useful, as a way to literally see what our users will see when they use our UI. These are great for checking font size, density, contrast and color choices. Sometimes it can be hard to put ourselves into the shoes of our users, but this tool makes it literally just a click away.
The aria-live-storybook-addon
is also a handy one to add—it adds a new panel to the drawer called “Aria
Live Regions,” which will show any time an action triggers an aria-live
announcement, as well as whether it’s polite or assertive. This way, we can confirm that announcements are triggering correctly when
new content is added to the page, and that the correct type of announcement is being made.
Finally, storybook-addon-psuedo-states
allows us to quickly toggle through all possible element pseudo
states from the Storybook menu bar. This add-on basically duplicates the functionality of the “Toggle Element State” tool from DevTools, but without us ever having to leave Storybook.
Pseudo states are incredibly important for accessible development—especially the
focus
and focus-within
states. Any users who use a keyboard as their primary method of navigation will need a clearly visible focus in order to find their way around. Some elements,
like buttons, inputs, etc. have focus states built in—but occasionally, we’ll need to add a focus state to something that doesn’t automatically have one.
Most design systems include new styling for the focus state, since the default blue highlight doesn’t usually match … well, anything. Being able to easily design, develop and test these within Storybook is a huge advantage. This is also hugely useful for checking colors and contrast on your hover, active and visited states. Remember: if we have a button that’s only clearly readable in some—but not all—interaction states, then we don’t have an accessible button!
As I hope you’ve seen from these two articles, design systems happen just as much on the development side as they do on the design side—don’t be fooled by the word “design” in the name! For a design system to truly be integrated and applied to an application, it needs to live in the codebase as much as it lives in the design software.
Thankfully, we have lots of tools—like Figma, Storybook, the Kendo UI component libraries and the Progress Design System Kit—to help us bridge that gap and make sure we’re keeping things in sync. When we embrace the use of a design system, it doesn’t take long for both us and our users to see the benefits in our website or application.
Kathryn Grayson Nanz is a developer advocate at Progress with a passion for React, UI and design and sharing with the community. She started her career as a graphic designer and was told by her Creative Director to never let anyone find out she could code because she’d be stuck doing it forever. She ignored his warning and has never been happier. You can find her writing, blogging, streaming and tweeting about React, design, UI and more. You can find her at @kathryngrayson on Twitter.