Communicating Aesthetic Sans Behavior
We have an incredible design team. Our collaboration has been one of the main reasons our frontend development team has been successful. They have a lot of insight into building well-structured design systems, and I learn something new from them almost every day. One of the best things we’ve done in collaborating with them was shifting from page-based to component-based design. I’d like to share a bit about how we came to that decision and the benefits we’ve seen.
From my experience, page-based design is the standard approach for design-development coordination. The concept of a website as a collection of pages drives the design process. And it makes sense to build applications this way. Pages provide context for components. They help users understand their purpose, function, and behavior. For example, when we see a login page, we understand the context of the email and password form presented to us. We can also assume its behavior when a user provides an invalid input, and how it would function when they are successfully authenticated. Not only that, this coordination comes with fairly defined roles and responsibilities. Designers are equipped with tools that focus on communicating design aesthetic, and developer tools are more geared toward controlling behavior and functionality. I usually see this process working out in some variation of this:
- Designers create initial page mock-ups based on client input
- A project manager and/or a team lead divides mock-ups into tickets for developers
- There is a “hand-off” to the development team to implement what design has created
- As designs iterate, new tickets are created, and the process repeats
With sufficient oversight, this process can be very successful for design-development teams, but it’s not without its issues. I saw a great tweet a while back that illustrates this point:
This tweet is specifically about test mocks, but it also speaks to the limitations a lot of design tools. While page layout and component styling are very important, they only represent a small part of their intended design. Many design tools struggle to accurately describe the behavior and functionality of components. And even though we have fantastic designers, they were spending a tremendous amount of effort attempting to communicate every possible state within a page’s context. We found this process creates a significant amount of duplicated effort, even with top-notch tools.
At the same time, our development team had tickets coming back from QA. And a lot of these were because component behavior was not as expected. We were getting hit from both sides.
We needed a better system.
Enter Component-Based Design
Several major influences led us to a component-based design system. The first was React, which our frontend team uses for developing our applications. React is structured around components, and as a result, our development team thinks in those terms. Brad Frost’s Atomic Design pattern and BEM methodology also provided significant inspiration. At the same time, our design team found that isolating components and their various states allowed them to more clearly articulate their behavior and functionality. They still create pages to describe user flow through the application, but they no longer need to explain every hover and error state within the context of that page. By first creating isolated, extensible components, we were able to remove a lot of duplicated effort on both teams. It also transformed our process. There’s less of a hand-off and more continual collaboration. Our design and development team members better understand the other’s intent and constraints.
So what does this process actually involve? First, our designers sorted common elements from our UI. This wasn’t an exhaustive, all at once approach. If I remember correctly text and header elements were some of the first to be documented. There were also links and a couple types of buttons. It was not easy, but it was enough to get started. These UI elements were then added to a guide to display their various states. For example, buttons have a default, hover, active, and disabled states.
Once these components were documented, our development team created tickets to build them in a separate component library that could be imported to any of our applications. Our reasoning for building components outside of our application was to keep them stable and versioned. This also allowed our design team to inspect the design and behavior of these components before they ever made it to our application. We also added tests to ensure these components would not change unexpectedly. Once these components were verified, they were slowly integrated into our application.
An Ongoing Process
This is still a live experiment, but the results have been great. Our components are stable, our developers don’t have to think as much about creating new one-off components, and our designers have streamlined a lot of their process. Another great side-effect is that component-based design encourages communication between our teams. We are engaged with our designers’ process, and it allows us to ask questions as we go. It also provides opportunities to give feedback. These tight feedback loops allow us to get it right the first time. And because of our React component library, we can be confident our UI is stable. All of this adds up to a productive, consistent designer-developer workflow and a consistent user experience across all our applications.