A design system on a shoestring, 3 years in the making.
I joined Thomas Cook Airlines to work on the UI designs for a new flight booking system.
The design of the booking app had already begun and was rapidly evolving and older designs were falling out of step. There was no central source of truth or conceptual documentation for buttons, form elements or larger components.
As the project was was new, there was a lot of iteration and re-evaluation of UI elements. The artwork was exclusively maintained in page-level PSDs. Even a slight tweak to a button style would require the agonising update of many Smart Objects and Layers in hundreds of PSDs across three hard breakpoints. After dutifully adding lots of unique button classes to deal with the variations, the developers were the first to spot inconsistencies between elements — which for a “pixel perfect” designer is irritating.
The debt restructure
We had to get serious with our UI elements. Based on their feedback, we conducted an audit of all the UI work so far. We collected every UI variation and type style across the whole project and ran sessions to agree between the whole UX and UI team which styles would be the best global style.
I wasn’t too enamoured with the look and feel of the first UI kit. But the review sessions were the first steps towards a design system. They teased out the thinking behind each UI element — for example the hierarchy of button styles or why and when we use icons. They helped us to begin to define usage rules around the elements and debate a team-wide approach to solving common interaction problems. They solidified the first iteration of our design principles.
The Sketch migration
After the audit, it wasn’t long before I pushed a switch to Sketch and got to work with symbols. Front end development had already begun in Angular. Without the time to go back and recreate all the page-level artwork from scratch in Sketch, this migration happened organically as we moved across sprints in various projects. Even now, some of the oldest designs are still in Photoshop, but the vast majority of page level designs are now properly documented and connected to Sketch symbols, which have the same or similar names as their css counterparts.
My UI kit sketch library file started simply, with the most common elements classified and codified. Almost straight away, I was able to start feeding the unified UI kit elements into dev sprints. Even though it caused more rework in the short term, the developers received the UI kit enthusiastically, as they could see immediately that much more time could be saved later if we organised and named our UI elements in the same structure as their code.
But we found this type of design debt is expensive to pay back: One entire dev sprint was spent deleting redundant button variations and unifying these button classes in the developed code. It would have been far cheaper to set up a component-centric workflow at the start, and allow the UI kit to evolve whilst retaining the ability to update symbols in projects without changing css class names. It’s a chicken-and-egg situation though, since most elements can’t be fully validated or tested until they appear in page level designs across a whole project. This was the first hint to me that a design system can’t be designed. It emerges from a lot of other designs.
We’ve now reached a point where all of our UI elements are connected to a UI kit and component library shared with Google Drive. This was an enormous improvement over the PSD workflow. We discovered Sketch has it’s own limitations, especially around version control, and we have to be extremely careful when updating the library, not to overwrite each other’s work or break things.
We tried a few version control services like Plant and Abstract, but these seemed a little overpowered for our needs — not to mention the requirement to train up designers on the developer concepts of branches and merging. So the UI kit still sits in Google Drive. As long as we communicate well enough when we’re updating it, we haven’t lost any work so far.
After establishing the UI element library, we felt confident enough to begin documenting more complex patterns.
Design principles are an important aspect of a design system. Web designers once had a limited palette of interaction options, restricted by user ability and browser compatibility. But interaction patterns have come a long way, driven by mobile devices and touch interfaces, which are much more organic and intuitive.
With so many different ways to solve an interaction problem, group reviews of interaction designs can get long and intractable. The design principles help resolve discussions of principle, by expressing an intent behind the choice of interaction. Here’s the ten principles we established for the flight booking engine:
- Sell the flight first — We don’t have a customer until they make their first purchase
- Separate content from config — Separate the decision to add a product from the more complex interactions to configure it
- Make choices transparent -The customer must understand the results of the decisions they make
- Don’t confirm — Be tap-friendly. Avoid unnecessary submit buttons
- Make undo easy — Customers make a lot of mistakes, don’t tie them in
- More meaning, fewer words — Keep it short, remove extraneous words
- Focus attention — Present one decision at a time
- Help customers learn — Make a consistent language of interaction patterns
- Think big, think small — Design interactions optimised for all devices — try not to create two experiences
- Goals & tasks first — Prioritise customer tasks over a neat IA
One of the criticisms I would level at digital airline experiences are the large number of different interactions used to convey the complex business rules around ancillary products. Each different UI control increases cognitive load slightly. The overall impression conveyed is one of complexity. We were proud to find a design pattern that worked for all our ancillary products with minimum variation.
The ancillary overlay pattern we devised expresses these design principles.
Sell the flight first — To reduce friction we allowed the customer to check out for their flight without seeing any of the complexity around products. There’s a single call to action / decision point around each ancillary product before the configuration begins. Other sites put the configuration up front, pushing several simultaneous decisions onto the customer.
Separate content from config —Persuasive content is presented in the page, configuration actions are completed in the overlays. This allowed us to keep our sales messaging persuasive and focused on the single decision to add the ancillary product.
Focus attention — Value judgements around ancillary options are usually multi-dimensional decision, but we presented one decision at a time, simplifying the decision making process to steps.
Don’t confirm — Selections are made instantly, without an additional click
Help customers learn —Unlike other airline websites, all the ancillaries follow this interaction pattern or a close variant.
Think big, think small — With a fast growing mobile booking segment, we prioritised the mobile/touch experience. The desktop experience was enhanced later — but we tried to bear all platforms in mind.
The component workflow
After establishing the principles and their relationship to the design patterns, we tried to improve our component design workflow by delivering component-level specifications rather than full screen designs. Previously the developers were making educated assumptions about alignments and constraints, these deliverables made all of that explicit with markups overlaying the designs.
There was some resistance from some designers who were used to publishing full page designs to Zeplin without markups. For them, manual markups were a step back. But we persisted in trying to persuade every designer to get on board with this process, because it made them think more explicitly about the underlying intent behind each small design decision. Creating Sketch symbols for the markups sped this process up a great deal.
This was a big step up in the volume of artwork and documentation. The strain of having a small design team without dedicated resource began to show. The extra markups step caused about a 50% increase in workload. Developers were much happier with our documentation and it cut their time down, but it was difficult to demonstrate the value of this extra time to product managers, who were rightfully focused on delivery of their features.
Not only that, but 40 components had already been deployed, meaning we’d have to go back and bring all the artwork for them up to scratch.
As a result, the component-centric design process was implemented more haphazardly than I hoped. But at last every designer was thinking component-first, rather than page-first.
Joining the Jetset
After we had refined our UI processes, we enlisted the help of the UX team to begin to organise our elements and components, so that we could plan our design system site. A lot of great UX and UI work went into the IA, the navigation and content of this site. It turned into a really good looking, well thought out design.
Developers, developers, developers
Our excellent development team at Incendiary Blue had already begun to manage their codebase in a similar structure to the site we had designed. Their ultimate goal was to have a set of versioned Angular & Vue front end snippets that could be invoked in the IDEs by a simple abbreviation. The foundation work in vue.js allowed the near-automated generation of a basic design system site. Unfortunately, we didn’t discover this until after we had the Jetset template designs finalised.
In retrospect, using this code as a basis for and MVP, and incrementally improving it would have saved a lot of development effort. Instead, Jetset was envisioned as a brand new product with it’s own templates and components. With no developer time to commit to building these new templates, development was repeatedly put on a back burner.
The hard lesson we learned from this is that a design system is an emergent property of continuous cycles of design & deployment. You can’t immediately jump from zero to material.io.
Where we left it
Thomas Cook moved digital operations up to Manchester, and the London team handed over the design system work before disbanding.
Many posts about design systems recommend making the design system into a product. This make sense — A design system has it’s own users, use cases and success metrics. But what if you don’t have the luxury of dedicating multiple designers to the product?
At Thomas Cook Airlines, we were already overwhelmed with projects, replacing the CMS, launching a cross platform React Native and Angular app built on a new set of web services, as well as implementing product changes for the rapidly evolving airline business.
The operational budget didn’t account for changes in design operations, which usually add overhead to urgent changes to the website. This overhead is easily ignored in the rush to get things built. Design and technical debt quickly snowballs to an unmanageable size. Design begins to cost more, take longer, and reduce in quality.
The other challenge was keeping the developers engaged in the process. Despite their enthusiasm, from development tokens to understanding the shortcuts available in modern front end frameworks, we didn’t take advantage of the technical tools in order to pair back development effort enough to produce the MVP.
The most successful part of the initiative was devising and bedding in component-centric thinking, which made for a quicker design process across all projects, and a more robust and consistent codebase.
Thanks to the all the team who worked on this project —Rich Smith, Marceli Cieplik, Mo Baghdadi, Paul Mason, Lee McIvor, Phil Benoit, Bianca Theunissen, Alex Joe Katz at Incendiary Blue.