Team Liquid Design System

Designing Modular Systems to Enable a Sustainable Future

Overall Impact

  • Design to Development time reduced by up to 400%.
  • System usability increased by ~2.5x.
  • Projects nearly 100% WCAG AA compliant (a 35% increase).
  • Bundle sizes were reduced by almost half.
Table of Contents
  1. Context
  2. Uncovering Patterns and Systems Trhough Research
  3. Crafting Systems as Challenge Solutions
    1. (Musical) Recursion as a Creative Superpower
    2. Breaking Down Patterns into Reusable Systems
    3. Accessibility as a Core Driver
  4. Outcomes
    1. A Big Impact on Projects
    2. Improvements That Could be Made
    3. Important Things I Learned

Context

In the 2010s esports saw what can only be described as massive growth. Dozens of titles emerged that would shape the industry into a global phenomenon. And this created enormous pressure on organizations to keep up with a scene that was developing at an incredible pace.

A timeline of major releases, including all of the major games (League, Counter-Strike, Dota, Valorant, etc…), and 15 different games over a 7 year period.

Team Liquid was one of the biggest organizations at the time, with a established and vibrant community. But it was clear as time was compressing around us, that in order to keep up products needed to develop faster, be more adaptable, and offer a better user experience. And there were a couple of big internal challenges driving this need:

  • Most product work fell to teams of 1-2 individuals, making every choice of what to work on important.
  • There was a lot of friction around creating and maintaining projects. Team Liquid’s codebase for example was extremely fragmented, and difficult to adapt or maintain.
  • The user experience for projects was cognitively burdensome, difficult to use, and largely inaccessible.
  • With only a style guide to use, every project started from zero. And that meant spending time reinventing the wheel (not a good use of time).

It was clear that to solve these challenges Team Liquid needed a framework that would enable the limited resources we had to do the best work possible. And a design system was the ideal tool to help reign in the current chaos of product work and enable a more sustainable future.

Setting Goals and a Strategy

Approaching this project, there were a few big outcomes I wanted to have based on the challenges that designers and developers experienced (both of which I led at the time):

  • Reduce the overall design/development time for any project by systemizing ideas into reusable components.
  • Create a strong baseline for the core user experience, especially in regards to a user’s cognitive well-being and accessibility.
  • Allow designers to create many different approaches with the same underlying core systems.
  • Optimize aggressively for performance (performance is king and all that).

Uncovering Patterns and Systems Through Research

In part because of how fragmented and chaotic the codebase was at Team Liquid, I really wanted to lean into a maximally efficient solution. One that minimized bloat and optimized performance. But that wasn’t possible until I really understood how patterns and systems interacted with each other on a deeper level.

App-like tiles, representing the UI audit and design systems research (including IBM, Google, and Apple).

Understanding consisted of two research tasks: auditing components and patterns that already existed in community projects, and reviewing popular design systems to get a sense of what patterns were more common and how they contextualized their ideas.

The most important things I learned from this research?

  • What a “pattern” was depended on the level of abstraction I was looking at. And many existed at multiple levels when I started evaluating each level as a holistic picture.
  • Existing spatial systems (e.g. 8-point grid), while helpful in many ways, were creatively restrictive and sub-optimal for performance.
  • At some point in the experience of a user, grid layouts became a blocker for flexibility and optimal UX.
  • Great typesetting inherently required several rules to be followed to be achieved.

This showed me was that there was a major opportunity to simplify ideas and themes into more abstract and reusable structures. And, several choices I might want to make about scale and rhythm were already partially predetermined.

With this knowledge in mind, I could start diving into more practical solutions.

Crafting Systems as Challenge Solutions

(Musical) Recursion as a Creative Superpower

The first, and biggest challenge I wanted to tackle was how to organize space and rhythm in projects. These elements affect typesetting, interaction patterns, and a user’s cognitive experience with the product. So they were essential to get right early. And I had a strong sense of the approach I needed from what I had learned.

A form showing spatial relationships (and asking why), typesetting guidelines, and a note about peformance being king.

While a viable option, existing spatial systems like the 4/8px grid all had one drawback: the logic of how to set space in relation to other spaces is largely arbitrary. As a result, additional systems are needed to express that information for designers to succeed.

Good typesetting also comes with a few rules to follow: a size that lets the typeface work optimally, and an appropriate (and different) leading for headings and copy.

Add to these the goal of maximizing performance, and I quickly realized that I could use a single technique to unify everything into a single solution.

Recursion in Music Composition

Recursion has been a popular compositional device in music for a long time. But it truly came into prominent use in the mid 20th century when composers started using it to create entire pieces of music from a minimal amount of musical material (sets).

On a trebble staff, the notes E, G, and F creating the {031} set. And on a second staff, showing each beginning note of three sets following the same {031} set pattern.

This is the most economical use of material possible, and was constantly in my head as I was working through this project.

Applying This Idea to Spatial Relationships

Translating a similar recursive system into the design world was simple, as typesetting already provided the foundation needed. And this came with several different benefits and new opportunities:

Foundational typesetting being used as the base unit and scaling factor in a spatial system.
  • The recursive logic could be used to create predicable and harmonious relationships.
  • This same logic also would make it easier to make decisions in the future as more information (components, systems) would reinforce the core ideas in play.
  • It would aggressively minimize style declarations (smaller code footprint).
  • Because everything revolved around an adjustable logic, it would be simple to change any of the core parameters to create different results (flexibility).
  • The core recursive logic was also fundamentally accessible being driven by typesetting needs.
  • It opened up the possibility to use a grid-less layout and lean into the naturally fluid state of digital products, improving flexibility/maintenance.

But as much as the benefits were great, there was one downside. A perfect system would create sub-pixel rendering challenges — one element even-pixel grid systems tackle well. To solve this, I decided to modify the logic to return the nearest even number, making a slight compromise so that designers wouldn’t need to memorize specific situations that needed pixel accuracy

The final spatial system, rounding to nearest integers to prevent sub-pixellation.

The resulting scaling system both helped to ideally set type, and used only 16 different sizes to enable every spatial relationship in the product (for reference, most products use at least 30+).

To really understand how much this affected the entire design system however, I need to talk about the most important goal.

Breaking Down Patterns into Reusable Systems

When I began the project, the central problem for Team Liquid was that design was a monolith. And this created several problems for the usability, efficiency, and maintainability of any project. So it was clear that breaking down patterns into understandable, reusable systems was necessary. But what wasn’t initially clear was how far should I go.

The first version of the pattern library, which focused more on components than more abstract systems.

My first explorations focused on creating a solid pattern library around the components we needed most. But as I started working on the scaling system, I began to realize that

there was a big opportunity to abstract concepts down to their base level to align with the goal of achieving maximal flexibility and performance.

Rhythmic spacing isn’t traditionally thought of as a “component” for example, but the concept is inherently thematic. And the same is true for for horizontal and vertical spatial relationships and many other ideas.

It was also the layered nature of the recursive system that also signaled that I should expand my vision around what a system was. So I began to break down and recontextualize themes in a design system to arrive at the eventual solution.

Systems at the UI Layer

On the UI side of things, I came to the conclusion that there were inherently 6 layers that ultimately governed build patterns. And it was the latter three that traditionally held most of the design complexity:

Visual examples of the six layers of the system: systems, regions, sections, blocks, components, and pieces.

Separating layers in this way enabled clear rules to be set around each one. For example, sections only concerned themselves with the vertical rhythm of content within a region. And similarly, blocks only handled vertical rhythm within a section.

A section element, with bottom padding.
A block element, with bottom padding and spacing when in a grid.

But the real power was in being able to combine systems within other systems. Layout rhythms, while part of sections and blocks, were governed their own relationship (S2) similar to a traditional type scale.

The rhythmic system, showing the 6 spacers, and the predominant S2 and S1 relationships.

This helped designers understand which sizes to apply in which context, without ever needing to define that context.

Similarly, because of how the core system treated concepts as lego-like blocks, components could be build around an abstraction that created a unified and predictable behavior within component families or contexts.

The core design of a class of components (at S3), and an example of how this class applies to many components to create alignment across buttons, form fields, tabs, tables, and other components.

For example, buttons, table cells, form inputs, and other control elements might all coexist in the same space. And by defining a scale that applied to each of these elements — for example S3 (an aesthetic choice) — an entire class of components (or visual style) could be implemented in a predicable way.

Honestly, it was actually pretty incredible to see how defining low-level concepts led to an incredibly quick and efficient result. But that’s not where the modularity ends.

Systems at the Build Layer

Not every project needs a card component. But every project needs systems around the core concepts (colors, type, etc…) and the artifacts it uses.

So, to maximize modularity, flexibility, and performance, I decided that the entire system itself should also adopt the approach that was developing and treat components and systems as swappable modules.

Modules that can be included at each layer of the system: from the foundations [principles, core rules, color, space], to the project fundamentals [type, colors, space/scale, aesthetics, composition, core layer], and pattern library [core components, general purpose, and specific components].

Taking this approach, while a little more organizationally complex, has a massive performance benefit as we could organize the codebase to pull in specific packages as a project needed it. It also enabled another big benefit.

Because any project could essentially swap out the typesetting module or core spatial properties, many different projects could rely on a single core system that could be extended to achieve different results (and do so in a highly performant way).

Two component groups both using the same core system but different type and spatial properties to create different results.

Accessibility as a Core Driver

Of course, as innovative as this approach was, none of that mattered if the core user experience didn’t create also the best outcome for users. And I began this project I knowing that meant the foundations for the entire system had to focus on accessibility.

Recursion Driven By Accessibility Needs

Because the entire spatial system revolved around good typesetting practices and a fundamentally adjustable logic, several important WCAG criterion were automatically covered or easily met.

Component designs meeting several WCAG criterion automatically (target sizes, text resizing, text overflow, and adjustet typesetting properties).

The spatial system was also aggressive in protecting a user’s cognitive well being. Older projects from Team Liquid were dense and overwhelming, and by setting the system around a comfortable unit size, products could breathe more, help users better understand structure, and help users make better decisions. It also was adjustable, in case we ever wanted to let users make their own changes.

A Compromise to the Color System

When I began designing the foundational color palette, I knew that I had to limit the total number of colors so that it would be easy to build project-specific sets from this core system. But this approach comes with a challenge: how do you ensure the selected colors will meet contrast requirements (and will still look good…especially in WCAG v2)?

The first part of the solution was in building a logic that sampled colors at “meaningful contrast intervals” so that the results gave enough options to have the right flexibility for many possible situations, and be close enough to important requirements:

The core color palette showing how each color band follows a delta value to create each swatch, and includes the contrast value.

As good as this approach was however, it was impossible to nail every possible situation because of the larger step size… and the non-linear nature of color. So a compromise was needed.

I decided that when choosing colors for a project, that for any swatch a deviation of ±0.3 would be an acceptable margin of error (e.g. a contrast ratio of 4.2 would be “okay”). This would allow better overall results, while still trying to adhere to the requirement as best as possible. But some judgement was needed on the designers part.

Color swatches taken from the core palette to create the main project colors. Arrows show how each color relates to for contrast situations.

User Needs and Flexibility

Finally, because the approach to the design system was inherently modular and scalable, we could allow users to completely change the core elements of the system to meet their individual preferences, whether we provided that to them in the product itself, or enabled it through other user agents (like browser settings).

Outcomes

A Big Impact on Projects

Project Chaos (its codename) was about 2 years in the making, starting with my efforts to modernize TeamLiquid.net, and continuing to mature through other projects. And it had a pretty big impact overall:

  • Design to Development time for projects was reduced by up to 400%.
  • For users, system usability increased by ~2.5x.
  • New projects were nearly 100% WCAG AA compliant, a 35% increase from previous projects.
  • Even with much more complex projects, bundle sizes were reduced by almost half.

Improvements That Could be Made

The first release of the design system was very successful. But even so, there were lots of places for improvement.

Because the core system was “highly economical” in its design, incorporating new ideas took more effort. And this slowed down designer’s abilities to craft project-specific components. This is partly the growing pains of any design system, but is could be helped by more clearly defining systems around structural combinations of elements (like atomizing image placements in components).

Important Things I Learned

Project Chaos was the first design system I ever built. And I learned a lot as I worked through it. However there were two important things that really made an impact on my thinking and approach.

Pain Points with Translations

More than anything, working on both sides of the equation as a designer and developer taught me a lot about where the biggest problems were between design and code, and how the conceptualization of a problem affects one’s ability to solve it.

A Flawed Color Algorithm and Good Intuition

Initially, I worried about how the compromise to the color palette might create more negative results for sighted users. However, I eventually learned about the deficiencies in the WCAG2 algorithm and re-tested the palette with the newer APCA proposal only to find that the compromises I made were shockingly close to complying with the new standard.

This gave me a lot of confidence to rely more on my instincts when I was assessing problems that were not “well understood.”

Back to Top