Due to my NDA, I have ommitted and/or obfuscated information and only show low-level mockups. My goal is to still be able to convey my process.
I've been fascinated by the concept of design systems ever since I first heard of them. After joining Proctorio in 2019, I began working on one as a side-project. With internal support, it eventually grew to become a core part of the company's future software.
This case study will be a bit more text heavy since I can't share some specifics or screenshots. But I'd still like to describe a bit of the process I went through and the lessons I learned on the way.
|My role: UX & Design Lead|
|Time frame: 2019—2021|
Justifying the investment
This began as a side-project for me. Since I was the only UX designer at the time, I didn't need to convince anyone about it. But as the scope of the project began to grow, the need for bridges with engineering became more evident. The following factors were key to get support for expanding this design system:
- Implementing the same UI element multiple times led to visual inconsistency, but also negatively affected accessibility. Accessibility fixes made to one element did not carry over to others.
- Slow collaboration between design and engineering. This was made more challenging by the fact that the engineering team is entirely located in Serbia, while I was working from Arizona.
Choosing the right tool
When I joined the company, most designs were made either on Illustrator or Photoshop. Since I just love looking into tools and there was an obvious need for it, I set off to look for a good solution to house our design system.
The obvious first thing to try was Adobe XD, since the company already used Adobe software. But some big limitations with their symbol system at the time raised a big red flag. For example, I remember not being able to resize instances.
I then played around with Figma, which I had already used substantially before. While it also had some limitations, the way it managed components and shared them across the team was very appealing. The computer scientist in me also loved their APIs, which open up some very interesting possibilities (more on that later).
Figma it is.
A unique or adaptive visual identity?
Proctorio's UIs are embedded directly into different testing platforms (e.g. Canvas, Blackboard, Moodle etc.). When I joined the company, the general idea was for Proctorio's UI additions to be almost invisible to the user, mimicking each platform's UI design and Information Architecture. In other words, users should think that's just part of the platform they're already familiar with. The idea was to leverage familiarity with the platform to make the software more usable.
However, this approach of adapting our UI to each platform brought many drawbacks:
- Slower development, since designers and devs have to adapt the UI to each platform.
- Each platform’s UI, accessibility, or Information Architecture issues carry over to our UIs.
- The same Proctorio functionality is located in different places in each of the platforms. Support content has to be tailored to each platform.
- If platforms change, we have to change too.
- Institution-specific customizations are not taken into account.
Based on these drawbacks, I chose to define our own visual identity and keep it between platforms.
Defining the visual identity
Previously the UIs were using two different fonts: Lato and Roboto. This was in line with the previous approach, since these fonts were used by some testing platforms. However, there was a third option, since a recent rebranding used Proxima Nova for Proctorio's logo and marketing assets.
Given that we wanted depart from blending with the platforms and prioritize our own visual identity, we chose to move ahead with Proxima Nova.
As a fruit of the work on this design system, we also revised the typography on the marketing materials and stopped using Proxima Soft, which is a rounded version of Proxima Nova. This style seemed a bit too playful for some of our contexts, and contrasted slightly with our illustration styles.
Proctorio's primary color is a bright green. While the initial thought was to use is as the main accent color, its prominent use brings a couple of fundamental issues:
- The primary shade does not have enough contrast against white.
- It can clash with the branding for different institutions. Imagine an institution whose colors are maroon and gold being complemented with big splashes of green.
As a result, we chose to use our dark grey as the primary color, using green only for accents.
At the beginning of this project, my team was comprised of two more people—very talented in illustrations and motion graphics. As I don't have a background in illustration, I wanted to give them ownership of this process, but I also wanted to make sure the new style met our internal requirements. So I proposed the following process:
- Each one of us generates a moodboard of illustrations, focusing on different styles.
- We went over the moodboard and grouped the illustrations into broad categories.
- We identified characteristics such as stroke, use of fill, physical attributes of characters, etc.
- They would both separately create different samples of illustrations exploring those illustration characteristics.
- We would then together narrow them down into a few options that all three of us liked.
- We presented these options to the company's leadership for approval.
The result was an illustration style that was fun but not overly playful. The use of simple lines and a very reduced pallete made the style scalable, easy to animate, and able to fit well in varied contexts. But limitations appeared over time, forcing us to evolve the style over time. The key to evolve it was:
- Two new graphical designers/illustrators joined us in mid-2020, bringing fresh perspectives.
- I promoted our senior designer, put her in charge of the two new designers, and gave them ownership of the branding and illustration style. The similarity greater similarity in between their backgrounds (as opposed to mine) and a looser process were seen as helpful in evolving the style.
The illustration style then evolved from simple lines and solid fills to the use of textures, shadows, and patterns.
Building and organizing the tokens & components
Following the approach outlined by Brad Frost in his Atomic Design book, I began building some base components such as buttons, checkboxes, and form elements. I also defined tokens through Figma’s text, color, and effect styles.
Component library ≠ design system
At this point, having a component library already helped with quickly building mockups and iterating on them. But most advantages were restrained to me while working on Figma. We weren't yet being consistent with our typography, colors, and illustrations in the marketing materials (usually done in Illustrator), and collaboration with engineering often still depended on specification PDFs or a series of back-and-forth emails.
To improve consistency within the marketing materials, we created a set of design tokens within Adobe's cloud solution, which provided consistent colors, typography, and assets. This library was owned by the graphical designers themselves, who kept it synced with the tokens in Figma.
As for the integration with engineering, the golden opportunity appeared when I began helping more and more often with the front-end. At first, this was just with CSS and HTML. But this still presented difficulties in the handoff. We needed some way of building reusable front-end components that included not only markup and styles, but behavior as well. Due to internal requirements and preferences, using one of the common frameworks such as React was not an option.
So I began working not only on a front-end component library, but also on an in-house framework.
First try: wrapping around the current stack
- Component styles were affected by the platform they were embeded on. So a CSS reset was necessary, which made the code larger and brought a host of issues.
- Composing components was a nightmare due to limitations with the templating library.
Version 2.0: web components were made for this
I first came across web components while working on the first version of this framework. I soon recognized that their characteristics would directly address some of the issues I was facing:
- Scoping of styles! Now the styles from the pages we're embedding our UIs onto no longer affect our components!
- Easy to compose elements using <slot>
- Components can easily be used with the previous tech stack for gradual migration.
The web components API is pretty low-level. So I built a superclass that encapsulated some of the functionality. This class leveraged LitHTML as the templating syntax for the components’ markup. And while not used directly, LitElement was a source of inspiration for some features and syntax for this framework. Here's a brief overview of some of the features this base class provided:
- Fetch and cache remote resources for a component.
- Handles component rendering when properties are updated.
- Automatic type conversion for properties.
- Lifecycle methods for the components
- Dark mode support, either globally or per component.
- Registers the component based on the class name.
Other than the basic components, a big focus for me was to enable easy use of animations and transitions. So I created a module that provides transition functionalities using CSS animations, and several components that make use of that modules to add smooth transitions between states by just specifying a single attribute on the element. Another benefit of centralizing transitions is that they can be disabled globally for users who can't tolerate much motion. In fact, the framework by default respects the prefers-reduced-motion media feature.
Using the framework is as simple as importing the component's ESM module and using the custom elements on the page.
Giving it a home: integrating with Storybook
Perhaps one of my favorite parts of this project was integrating it with Storybook. This allowed us to have a homepage for the framework, with documentation, tutorials, and examples for each component. This was a key movement towards legitimizating the design sytem internally and promoting education and adoption.
One challenge throughout this process was to find good documentation on using Storybook with webcomponents. There were good examples, but they were nowhere near as ubiquitous as those for using React with Storybook, and were occasionally out of date.
Connecting the front-end with Figma
At this point, we had both a component library in Figma and in the front-end framework I built. Now there is a gap between both of these libraries: if updates are made in one, how do we ensure they are also made to the other? Here are some ways I've attempted to bridge this gap.
Embedding Figma documentation into Storybook
I centralized component documentation in Figma. This way, I could embed Figma documentation directly into Storybook alongside examples of the actual components. Discrepancies between the design in Figma and in the front-end now are pretty obvious when looking at the documentation.
Syncing the icon library
Figma became the central source of our design system's icons. To allow the front-end framework to make use of that, I built a CLI tool that leverages Figma's API to export the icons from Figma. It normalizes the icon names into a standard format (used by some components to fetch the right icon). Finally, the tool then grabs the SVG generated from Figma and optimizes it using the SVGO library.
Linting the Design
I eventually abandoned this approach when it became clearer I was going to have ownership of the front-end components. Regardless, it remained an interesting option of keeping styles in sync between the design tool and the code.
Build the components alongside a project
The components I most often had to change were the ones I built apart from any projects. There is a big difference between harmonizing components together when they are laid out in a grid within a Figma file vs. when you're setting an actual page in a system. Issues with visual hierarchy become very evident, and small details that looked cool when you were designing that isolated component now just look noisy and distracting when you have 20 of them in the same page.
Use internal projects to advance the DS and build reputation
When there were no major projects to move the design system forward, I found that designing and developing internal projects was highly effective. Not only it gives you a project to develop components with, but the result can also bring attention and reputation to the design system within the company.
Time pressure is a big enemy to adoption
When teams are under pressure, having to learn a new framework becomes more of a burden than an opportunity. That is why having a very low barrier of entry is key. I've tried doing that by making it very easy to get started. This means a minimum structure needed to build the framework and a very clear and approachable documentation. I also had several calls with the engineers to train them on the framework.
Involvement in the process fosters ownership and adoption
Internally, I found support and adherence to the design system when I involved the team in the process. But involvement doesn't only mean having collaborators do some work in the sytem, but also shape the process itself. Take for example the illustrations. My first approach, in which I more closely guided the process, yielded some success. But the style only truly evolved when I gave more freedom to the illustration team. They enjoyed their work more and I began seeing more initiative on their end.
You need processes, roles, and tools to keep everything up-to-date
Our design system was always evolving. There was never a point where we could say it was completely done. This means frequent changes in components, documentation, tokens, designs, front-end, etc. And with frequent changes, you have to ensure the different parts of the system are being kept up to date. This involves having processes in place, having clear roles and responsibilities, and having tools to automate whatever you can.
But however important these things are, they are meant to regulate the maintenance of the system, not enforce its usage. Usage comes from the value teams get from it.
Figma: the good, the bad, and the ugly
Tools come and go. You can't get too attached, but it's always interesting to push their boundaries. Nowadays, Figma is one of the trendy tools within the design community and has become my tool of choice for design projects. Building Proctorio's design system allowed me to dive deep into Figma, especially its features that are geared towards design systems. Some of the things that resonate with me in Figma:
- The vector drawing tools remind me a bit of Flash, which got me started on web design.
- The fact that it has an API opens so many doors for the creation of tools.
- Components generally work very well, despite some limitations (more on that below).
Small bugs aside, perhaps my biggest complaint is the approach Figma is taking with auto-layout, variants, and interactive components. Every new feature seems to fix some pain-points, but introduce some new ones. For example, variants finally allow you to create customizable components. However, you may end up having to create an exponential amount of variants to cover all of your use cases. The more properties you introduce, the larger this number gets. And while auto-layout finally allowed you to create components that resize based on their content, only pre-existing parts of the content can change. Component's cannot work as container components. For example, a modal dialogue component only allows you to edit the text inside of it, but not to add or remove content to it. I wish they'd be willing to move over a bit more into the development side of things, although I understand them not wanting to cross that line.