Efficient Consistency with the Mosaic Design System

I am in a World of Shit

I am the type of person who is never happy with the current state. I believe there is always room for improvement; to grow, to change, to become better. The company I work for is also not afraid to change, to grow, or to become better. We need to change, because we are at a pivotal time in our history, the mission is clear and time to act is now. We are going to war and we need the best talent, tools and processes to win. As the president of our company Chris Johnson says “Better never stops.”

Years ago, all of our products, whether internally built or bought, looked completely different.

“I am….in a world….of shit.”
-Private Gomer Pyle

In a world of design shit, that is. Because our products functioned and met very important, real world needs, and ultimately saved many lives, they just did not look related. They also did not share common UI patterns, leading to a fragmented user experience.

“In other words, it’s a huge shit sandwich, and we’re all gonna have to take a bite.”
-Private Joker

And we did. We all took a bite. Our team can now say that all of our products look related.

It’s a beautiful thing.


Fast forward a year.

We started to explore ways to improve and create cohesiveness and consistency between Design and Engineering. I spent endless days and nights, dreaming and waking in the middle of the night, with thoughts and ideas on how to make it a reality. This was not out of stress, but pure passion for what could be.

The solution needed to fuse with the tools we already use, be automated when possible, create consistency across Design and Engineering, and serve multiple complex enterprise web and mobile applications of varying technologies.

We needed a way to consistently share styles, components, and UI patterns across multiple products.

Our products looked related, but they needed become a family. The goal was to create a system with one source of truth, that would automatically update and keep all our designs and products in sync.

To win this war, we needed to increase efficiency between Design and Engineering, create consistency, and reduce time to market.


Over the last year, our team at TeleTracking Technologies has been building our design system. We spent a lot of time in defining what a design system meant to us and most importantly how it could benefit us.

With much respect to the famous design systems of the world, this is a story of how ours is unique.

Mosaic is our design system.

The Mosaic Design System is made up of ideas, processes, patterns, principles and tools. And in this war, it’s our weapon of choice.

What is Your Major Malfunction?

We had inconsistency in many areas, including styles, UI patterns, naming conventions, language, CSS class implementation, and more. We had various problems to fix, but our major malfunction was inconsistency. We aimed to build a system to solve it.

Shades of gray from our platform. Discovered with curiosity and by auditing our CSS.
“I didn’t know they stacked shit that high.”
-Gunnery Sgt. Hartman

We did.


We had no centralized standardization or a central source of truth for design elements. One that could inform multiple products and projects. Our platform contained over 110+ colors and 23+ font sizes. That is just our recently built, cloud platform, and does not take into account several older product suites. Or mobile. This standardization could increase cohesiveness and consistency.

The amount of time we spent pixel twiddling and begging engineers to comply with our requests was costly. We needed centralized components that could be placed anywhere in the UI and scale size accordingly. They should be easily shared across all our products and projects. They should be getting their styles from the standardized source. This could increase efficiency and consistency, effectively saving time and money.

Our CSS was unmaintainable and we continued to accumulate technical and design debt. We only had product specific CSS, limited reusable classes, no standard naming conventions, no css pre-processing and a general direction in Engineering that CSS was the least important code. They had to focus on functionality over aesthetics. Our CSS, like our components, needed to be centralized, modular, object-oriented, and easily served between multiple systems. This could increase understanding, reduce code, and decrease maintenance.

We had designers and engineers approaching similar needs differently. We had no reference for up-to-date styles, components, UI patterns, and guidelines. An up-to-date resource with minimal maintenance could increase consistency and alignment.

Design and Engineering weren’t speaking the same language. We needed to refer to the naming of components, patterns, and SASS variables with common understanding. This shared vocabulary could create efficient conversations and reduce rework.

We needed an answer for our major malfunction; inconsistency spanning a wide range of areas.

Questions we set out to address.

Boot Camp (One Source to Rule Them All)

If we are going to win this war, with our weapon of choice (Mosaic, in case you missed it) we needed it by our side as we entered consistency boot camp.

Phase one of the Mosaic Design System was defining centralized consistent platform building blocks. Colors, icons, icon sizes, font sizes, shadows, border radiuses, etc. The lowest level of the UI that can be used to build any element.

Collaborating with multiple designers on the team we whittled the 110+ colors to a standardized set of roughly 18. We reduced the font sizes from 23+ to 8.

We did an inventory of all the icons used within our platform, named, and categorized them based off contextual use and created a standard set of icon sizes that match the defined font sizes.

We continued to define platform standards for the remaining building blocks such as spacing, gradients, media queries, animation timings, borders, shadows, etc.

These standardized styles became the Mosaic building blocks. They act as the source of truth and are used to build and maintain order across our products.


Next phase. We needed to name the building blocks defined in the first phase. To fill the void of a CSS naming convention/methodology we went with BEM. The BEM naming convention solved a lot of the issues we were having in our CSS. We had inconsistent naming structures, ambiguous class names and classes applied to inappropriate elements.

Abundant consideration went into naming the SASS variables and when to create a specific targeted variable name versus a more general name. We have some very general variables like $color__green where we style general branding elements and allows us to white label if needed. We also have variables like $color__error which we use for error icons and text. This allows us to target a color change to all error colors with one update. In certain situations we get very specific such as $color__text-field-label which allows us to update all the field labels with one change.


Once we had defined and named the building blocks, we needed a place to store them. We determined the building blocks should live in JSON files. The JSON data format is easily ingested by multiple systems across Design and Engineering.

We also needed to structure the JSON file in a way that made it easy for multiple systems to consume. The example object below is from our ui.color-palette.json file.

{
"variable_name": "$color__success",
"value": "1fb25a",
"uses": "Used for success feedback",
"category": "Messaging Colors",
"sketch_include": true
},

The "variable_name" and "value" attributes are used to create SASS variables. All of the values are also read and displayed in our Mosaic Design System website and Sketch plugin, but more on that later.

SASS variable created from the JSON file.

$color__success: #1fb25a;

These variable names are baked into both Design and Engineering workflows giving us a common language.


The living aspect of Mosaic addressed the remaining questions and I will get into detail on that in the next section. A change to a building block value will update that value in all designer files and all product UIs.

With standardization work complete and the main questions answered, Mosaic graduated from boot camp.

The Living Solution

The living solution allows our UIs to stay consistent across Design and Engineering. We can update multiple products and all our designer files with one change. The graphic below shows the ecosystem at a very high level.

All of the code, that makes up the living side of the Mosaic Design System, resides in our Mosaic-UI repository in Bitbucket. The Mosaic-UI repository contains the JSON source of truth files defined in boot camp, the SASS partials generated from the JSON, along with other assets. If something needs to be distributed across projects it lives here.

Adding more detail, the graphic below shows the living aspect of the Mosaic Design System and how Mosaic keeps it together. In the next two sections I will walk through each side of this graphic. I will explain in detail how a change to the source of truth flows through Design and Engineering.

Mosaic and Design

Mosaic keeps design files consistent across our team. At a high level this is how that happens.

A value is updated in a JSON source of truth file.

That update needs to propagate across the design team. Since all designers on our team don’t interact with code I wanted this to be an automated process and not force interaction with Bitbucket.

Sorry designer friends, it’s about to get technical up in here.

A simple shell script was created to automate the setup process. This was a one-time setup on every teammates MAC. The shell script generates an SSH key, creates the needed directories, clones our Mosaic-UI Bitbucket repository, and installs a cron job. Using SSH key authentication, the cron job does a git pull (gets latest code) every minute, from the dev branch in our Mosaic-UI Bitbucket repository. If the building block JSON files get updated, those changes will be on all designers local machines within one minute.

The building blocks are always up-to-date.


Previously, our design team used assorted applications. Some of us (me) correctly preferred Photoshop while others (you know who you are) incorrectly preferred InDesign. While we agreed to disagree on that, we all agreed on the fact that neither of those tools were meeting all our needs. After some trial runs with various applications we settled on Abstract, Sketch, and InVision as our main design tools.

The timing of this change, in tools and process, perfectly coincided with the implementation of the living side of Mosaic. This granted me the opportunity to write a custom Sketch plugin to complete the design pipeline.

I worked with a couple of engineers to get a custom Sketch plugin off the ground. I continued to develop the plugin through the summer of 2017 and learned more than I ever wanted to learn about cocoascript.

The Mosaic Building Blocks plugin is installed on all our machines. It’s one of the things that makes Mosaic unique.

When ran, the plugin loops through all the JSON files and renders the data in Sketch. The plugin utilizes all the attributes in the JSON file.

It displays the "variable_name” and "value” for each defined JSON object. The plugin groups all colors into their relevant "category" and lists the "uses”. Lastly, if "sketch_include” set to true it renders that object in the plugin.


{
"variable_name": "$color__green",
"value": "1fb25a",
"uses": "Green, don't use for text. See text colors.",
"category": "Base Colors",
"sketch_include": true
},

The Mosaic Building Blocks are now viewable within Sketch. Sharing the same source of truth between Design and Engineering creates consistency and enables designers and engineers to speak the same language, while also holding each other accountable. If a designer wants to introduce the 33rd gray into our platform a engineer can call bullshit. If an engineer wants to use a SASS variable strictly defined for text on a background we can call shenanigans.


The most powerful part of the plugin is the mapping feature. We can map colors and icons from the plugin to colors and icons within our Sketch symbol libraries. The ability to map additional building blocks is in our backlog. Behind the scenes, the plugin creates a unique JSON mapping file for each individual Sketch library document. The contents of the mapping file are similar to below.

[{"layer_id":"F597CBDE-D353-492B-8488-00E889E32965","fill_variable":"$color__icon-default","border_variable":"","icon_class":"glyph__collapse-all"},{"layer_id":"72EDDE94-A6E6-4EC8-81D2-DFEF3676D960","fill_variable":"$color__text-field-label","border_variable":"","icon_class":""},{"layer_id":"F01D4EEB-985A-4849-B841-FF6735244327","fill_variable":"$color__error","border_variable":"","icon_class":"glyph__error"}]

A object mapping is created by selecting a layer in Sketch and applying a fill color, border color, or icon. This creates a mapping between the unique "layer_id" (input field, icon, button, etc.) to the "fill_variable” and/or "border_variable” and/or "icon_class". In the mapping file example above we see the "icon_class" has a value because those unique layers are icons.

We can check if mappings exist on symbols by selecting their layers and clicking the “Check for Mapping” button within our plugin.

Below is an example showing the mapping of the $color__button-primary color to a Primary Button symbol in Sketch. And then checking if a mapping exist for the Primary Button layer, which obviously it does because we just mapped it.

We can also select multiple layers and check for mappings. The screenshot below shows that of the 4 layers that were selected in Sketch, 3 of them are mapped to our building blocks.

This allows us to understand what layers have been mapped to our building blocks without digging through JSON mapping files.

Now the best part, because better never stops.

When the plugin runs it loops through every page, every artboard and every layer, checking if a mapping exists. Each time it finds a layer where a mapping exists, it applies the value from the JSON file to the layer. If the color value in the JSON file changed, that layer gets updated to the new color. If a icon value changed, the layer gets updated to the new icon.

Let’s say we decided to make our primary buttons blue. We would update the hex value in the JSON file for $color__button-primary. The next time the plugin ran the button color would update to blue.

This updates the symbol in the library and every designer project using the symbol will get the update.

Example of the Mosaic Building Blocks plugin applying color update.

These mappings only need to be created in our Sketch symbol libraries. The mapping files for the libraries are checked into Bitbucket. A field label color, for example, can be mapped to the plugin. That field label symbol can then be nested into 15 other symbols (select list, text area, type ahead, etc.) using Sketch’s nested symbols. When the field label symbol gets an update from the source of truth, all nested symbols get updated. And every project file, across the team, that is using symbols from the library get updated.

Previously, if the color of a UI element changed, we would need to manually update all of our files, and hope that we caught every instance of that change. Now we can easily keep our files consistent without relying on memory or manual upkeep.

Mosaic and Engineering

Mosaic keeps our UI’s consistent across our products. At a high level this is how that happens.

A value is updated in a JSON source of truth file.

The JSON files along with the rest of Mosaic-UI is treated the same as all our code. The code change follows the same pull request (code review) approval process.

When the code change is merged to the relevant branch in Bitbucket, a build for the Mosaic-UI project is kicked off in Jenkins. The Jenkins build executes the Grunt build within the Mosaic-UI project.

The Grunt build reads the JSON files and writes SASS files on the fly. These files contain SASS variables and mixins, the building blocks of our design system. These variables and mixins are then referenced throughout Mosaic-UI to create and maintain consistency.

$color__orange: #f27d05;
$color__orange--dark: #cb6b0b;
$color__header-background: #ffffff;
$color__header-background--night: #111111;
$color__text-field-label: #666666;

Similar to our field label example above, if the value of $color__text-field-label variable changes every instance will be updated. There may be 6 components using a mixin similar to below.

@mixin text__field-label {
color: $color__text-field-label;
font-size: $font_size — x-small;
}

Every component using that mixin is updated with the change.

At the end of the Jenkins build process, on the master branch, it creates a Mosaic-UI NPM package and deploys it to the Mosaic ProGet feed.

The package is now updated with any changes.

Multiple enterprise applications, mobile and our living style guide all consume the Mosaic-UI package and get all updates.

Mosaic Living Style Guide

Like most companies, we struggled to create a style guide that is up-to-date and easy to maintain. Ours is the by-product of our design system.

The living style guide lives in our Mosaic Design System website. The Mosaic Living Style Guide consumes the Mosaic-UI NPM package and reads the JSON building block files, to render a up-to-date, low maintenance, consistent style guide.

It is a reference for Design and Engineering to view our standardized building blocks; color palette, variable names, icons, sizing and spacing variables, etc.

Our near future plan is for our Angular and React components, styled from our building blocks, to also live on the site. When those components update, so does our living style guide.

We wanted a style guide that would not become stale and outdated the minute we looked away. One that didn’t need to be manually updated to match style changes. Mosaic’s living system made that possible.

4112 Basic Military Journalism

“Jesus H. Christ you’re not a writer, you’re a killer.”
-Gunnery Sgt. Hartman
“A killer, yes sir!”
-Private Joker

So, a killer I will be, as we look to exterminate inefficiency and win this war against inconsistency. With Mosaic, as our ammunition of choice, we will efficiently march forward in perfect cadence. The system is ready and the time is now.

I am not a writer, I am a killer.


The passing of Gunnery Sergeant Hartman (Ronald Lee Ermey) on April 15, 2018 coincided with our internal release of the Mosaic Design System. I thought it was fitting to pay tribute to him, or at least try, as I am not a writer. May he rest in peace.

“If God wanted you up there I am sure he would have miracled your ass up there by now…”
-Gunnery Sgt. Hartman

We cannot expect to win this war without continuing to getting better. Nothing is going to be handed to us. We created the Mosaic Design System to give us the best chance to influence change and solve the problems we were facing.

Because “better never stops.”