A Shared Language Through Design Systems

06 Oct08:00 – 08:25 UTCTalk
Slides

Checking session availability…

Hang tight while we load the latest updates.

I am no expert on the subject of Design Systems but what I am, is bilingual. I grew up in graphics and design was my first language. I moved to development and lived here long enough to start dreaming in code.
What I am is an interpreter fast becoming adept at catching the subtle nuances easily lost in translation, acting as a go-between when designs are switched to code. Focusing on my team's journey on creating the spacing for Zoopla's design systems. I will touch on the:

  • communication challenges between design & engineering
  • the skills I used to be the bridge between both roles
  • process in creating a shared language between the product team, and
  • any future improvements I can foresee

A Shared Language Through Design Systems

Nathalie Christmann-Cooper at UXDX EMEA. Video: https://www.youtube.com/watch?v=4_7iv8fi_O8

Readable transcript: edited from the recording's captions for readability (fillers and false starts removed, punctuation and section headings added). Wording is the speaker's own. Timestamps are positions in the video. Names marked [?] could not be verified against the audio.

Bilingual between design and engineering

[00:00:00] I love design systems. I've watched talks on them. I've read books about them. Believe me when I say I've done my time studying the theory. But it wasn't until I started working at Zoopla, and that's been about 18 months now, that I've actually had the chance to really get my hands dirty working on a design system: to collaborate with both designers and developers on building a design system, to experience the teething pains of working on a design system that's in its infancy, and to appreciate just how hard getting this right can be.

[00:00:34] Now, I can hear you wondering why on earth you should carry on listening to me talking about design systems when clearly I'm no expert on the subject. And yeah, I agree, I'm no expert. But hang on a minute before you go. Stick with me, because what I am is bilingual, and let me take a moment just to explain that point.

[00:01:02] Once upon a time, actually quite a long time ago, I had this notion that when I grew up I'd be working in advertising. So I went off to study at art college, and my sketchbook went everywhere with me. I was all about the visual communication. I essentially grew up in graphics, and design was my first language. But a career journey takes its twisty turns when you start packing that box of life, and in mine there was marriage, raising two kids, plus running a home business; you get the picture. Eventually I came to a point work-wise where I got itchy feet. I was ready for a new challenge, and I decided to pack up my career bag and relocate to development.

[00:01:48] I've lived here long enough now that I've started to dream in code, and I can just about hold my own when the conversation turns technical. But unbeknown to me, having lived on both sides of the border, I was to find my niche as an interpreter, located somewhere in between the realms of design and engineering. I've become skilled at catching the subtle nuances that are easily lost in translation when design gets switched to code. So I'm talking to you now as that interpreter, about my team's journey in creating the spacing for Zoopla's design system.

[00:02:26] I won't go into the nitty-gritty of what we actually built. Instead, I'm going to focus on the communication challenges that we faced between design and engineering, how previous knowledge was useful for me to become the bridge between both roles, and the process that we took in creating a shared language that everyone can understand.

Design tokens at Zoopla

[00:02:50] I'm going to start by talking about the communication challenges we had, in particular when we started to work on our spacing design tokens. I'll first give you some context on the product teams and the design systems here at Zoopla. This talk involves the consumer teams, who work on the Zoopla website and app, and the customer productivity teams, who work on property software products for estate and letting agencies.

[00:03:21] Design controls a series of Figma files, and these are broken out into foundations and patterns. This is loosely based on the atomic design principles, and these files determine the basis of our component libraries that are maintained by engineering. To begin with, our design system served only the consumer teams working on the website and app, and we've started to build out a very similar pattern now for the customer productivity teams. That's actually one of the teams that I work in. And we've got a collection of centralized design tokens that hold all of this together, with an additional layer of tokens on top that are specific to particular products.

[00:04:06] I'm not going to go in depth about design tokens, but if you do want a starting point to find out more, I have included a link. Design tokens are variables that we use throughout our code, and they give us a single source of truth to control global styles, like color, typography and spacing. I've grabbed a few examples here from our code base for you to see.

[00:04:31] We were working on the first iteration of our version of the design tokens, and whilst doing so, we wanted to provide feedback to design from an engineering perspective: to voice concerns, ask questions and propose some changes. We took the opportunity to start discussions early, and this was important for a number of reasons. Firstly, if we can achieve consistency in how we name and apply our design tokens, we can build a shared language and understanding, not only between the functions of design and engineering, but also across our consumer and customer product teams.

[00:05:07] And did I mention that design systems are hard? Well, our experience here at Zoopla has not changed that story one bit. We're following hot on the heels of the consumer teams on our design systems journey, so we're really keen to make sure that we learn from previous mistakes, and communication is key to sharing those learnings. If we don't talk to each other, not just within our own teams but across the different functions and product areas of the business that are also using the design system, then we will disastrously keep making the same mistakes over and over.

[00:05:43] And lastly, we needed an agreement on the shared foundations now, because if any fundamental changes are made, then the code base built on top will have to be updated. And generally, design tokens don't tend to change once they've been set, so if we can make those changes early, then we can minimize any resulting impact. The spacing tokens were top of our list for concern, because we didn't like the current naming convention, which was linked directly to a pixel value. If this value changed, then we'd have to update all the tokens accordingly. So it made sense to us to stay clear of named variables and instead take an abstract approach. The proposal was to have a naming strategy that defined multiples of a base unit.

A proposal process for changing the design system

[00:06:38] But before we could even start that discussion, we realized that we didn't have any process in place for making improvements to the design system. So we decided to address this first and put together a new proposal process, which looks like this. The first step is to create an RFC, a request for comment. But this alone is tricky. We've got documentation in multiple places, like many places do. Engineers tend to put their documentation in Confluence and in Google Docs, and the source code itself coexists in different locations: we've got one code base in GitHub and the other in GitLab. Not to mention that our designers were documenting in Zeroheight and Frontify.

[00:07:23] So we needed to be confident that the RFC was shared where it would be seen, read and engaged with. We decided that the design system Slack channel was the most appropriate place to kick off the discussion, because it was the one place that everyone had access to, regardless of product team or role. That in itself doesn't guarantee that people will join in with the discussion. But if we can get consumer and customer tech leads to champion the proposal, and make sure that it has visibility in weekly update meetings, then we can safeguard against the RFCs gathering dust.

[00:08:03] We wanted to be mindful of any previous issues and the context around them. So we got in touch with an engineer from the consumer side, ran through our proposed name change to the spacing token, and then we listened. We knew that during design handover, Figma only shows pixel values. If Figma could display the spacing token name instead of a raw pixel value, then we were in agreement that an abstract naming convention for the spacing token would be an engineer's preference. But we weren't in that position yet.

[00:08:37] Because Figma only displayed pixel values, we learned that the reality is that abstract token names, right now, demand too high a cognitive load during handover. Designers think in pixels. The code base had a base font size of 16 pixels, but engineers then map that to rems, because that's the code base's unit of choice. This made it harder for an engineer to mentally map: spacing 5XS is how many pixels in Figma, and then what do I convert that to in rems? So our proposal had become a question: could we get Figma to display spacing variable names?

[00:09:17] In our quest for answers, we went to design to find out. At Zoopla, Figma is configured to use automated spacing, which doesn't use a token name. So the answer was no: Figma wouldn't show the token names. But we also found out that abstract token names are harder for design to work with, and there was some resistance, because this could make it difficult to insert an additional size in the future. The key learning was that designers need to understand the token names too. If we moved to using an abstract naming convention, we wouldn't be getting rid of the problem of cognitive load. We'd just be removing it from engineering and throwing it across the border to design.

[00:10:00] So it became clear that an alternative approach was needed if we wanted to make this work for everyone. We decided instead to reset the base font size for the productivity apps, to remove the cognitive complexity for ourselves as engineers. By resetting the font size to 10 pixels, we could keep to the current naming strategy, which directly referenced the pixel size, and we achieved a one-to-one mapping of pixels to rems. So instead of 16 pixels equating to one rem, 10 pixels was now one rem: 16 pixels is 1.6, 20 pixels is two, and so on. This eases the cognitive load for the dev teams, and it let us stick with the naming convention that's understood by the design teams. Success!

[00:10:50] We'd reached an outcome, the fourth step in our proposal process. The discussion had given us some very valuable information, and we needed to capture our learnings in a decision log. It wasn't the outcome we'd originally set out to get, but it was a compromise that still gave us the same end result. And this illustrates the value of keeping a decision log. It doesn't just record the outcome, but the why behind an outcome. In this instance, it wasn't the fact that this didn't result in a change to the spacing design token that matters. The important piece to log was the why not.

[00:11:26] This last step doesn't really play a part here, but we've since discovered that sometimes a discussion might only happen within engineering, or only in design. Regardless, if we want to make sure that we're all reading from the same page, then we need to make sure that we have procedures in place to keep everyone regularly updated, because otherwise it doesn't take long for parts of the design system to become out of sync.

Spacing between components and UI glue

[00:12:00] This next part looks at what happened when it was time to start using the design system. I was lucky to be in the first product team to do just that, and this is where that previous design experience comes into play. We had a basic selection of bricks, or components, ready to use, and we'd laid a solid foundation with the design tokens. But what about the mortar? How were we going to hold our bricks together to build new page layouts using these components?

[00:12:32] The problem is that components exist in isolation, without any context. The component doesn't know how or where it will be used outside of the component library, and it doesn't need to. To start building out new UI using the design system, we wanted to define the relationship between the components within a given layout, but we didn't yet have any means to control that spacing. So we looked at the consumer side to see what had been learned there. One of our principal engineers, Craig, had already looked into the app using the component library, and unfortunately he found that pretty much every component was UI glue. This issue of spacing hadn't been tackled yet.

[00:13:13] So what is UI glue, you ask? Well, good question. Engineers were adding containers around components to start attaching space to them. There was no set way of doing this: one might use margin, another might use padding, or even Flexbox. The app-specific components were becoming bloated with this UI glue, low-level CSS that was being added to stick components in the right place on the page. And Craig told me that this was the most important thing, after design tokens, that we needed to get right for the Zoopla design system.

[00:13:52] The challenge was to enable us to have a single way of doing layout. The longer we continued to create this UI glue to stick our components in place, adding in custom CSS each time we composed a layout, the higher the risk of inconsistencies and bad practice slipping into the code base. So, taking all of that into consideration: if we could use layout components to give us a set way of applying CSS for layout, then we'd improve standards and consistency. And with this new ability to add and rearrange components on a page without having to go in and manually tweak the CSS, we could do away with the worry of working out what CSS to apply, and speed up development time significantly.

[00:14:43] And once the spacing becomes a reusable component, we can remove significant chunks of UI glue from the code and take advantage of deduping and code splitting, which ultimately improves load times. So yeah, thanks, Craig. There was absolutely no pressure there, then.

Setting constraints for layout components

[00:15:02] I did some research into how this is handled elsewhere, so that I could start setting constraints. This was a little trick that I remembered from my designer days, to break the creative block when you're starting off with a blank canvas. A lot of the layout components that I looked at took a utility class approach to control spacing, by using a class. Maybe that's because some of them dealt with more than just spacing, like adding borders, applying background colors or setting text alignment. The examples shown here are some of Bootstrap's spacing utility classes.

[00:15:36] My concern with this is that it could become a kitchen sink, where more and more options are added in over time. We're trying to reduce bloat and make things simple, so where does the line get drawn on what gets added in? And opening up the React API property className is unlocking a back door that could be very tempting for an engineer to sneak in freestyle custom CSS classes, which then defeats the whole object of trying to maintain a consistent UI. These are spacing components, after all, and the simpler the API, the easier it's going to be to understand and use. So this set the first constraint: not to use the className property.

[00:16:23] Now, this next piece of research was the light bulb moment for me, translating this into terms that I understood as a designer, even though in essence this was an engineering task. Designers treat space as a physical thing, which is placed between elements. Space isn't directly applied to an element. A subtle difference, but very significant. It's obvious when you say it, and thank you to Mark Dalgleish for pointing that one out. Hold on to that point, because it pops up a few times.

[00:16:54] Early discussions had mentioned that we could maybe use an isolated spacer component, which at first glance does fit this line of thinking. But it has no concept of the relationship between a set of components which might need consistent spacing; think in terms of a list of items, for example. It also adds a lot more code: a separate spacer component is required to define each individual space. So that set the second constraint: to use relational spacing only.

[00:17:26] And I wanted to use margin to define the space between components. But because margin affects the space outside of whatever it is that you apply it to, it's not always a popular choice in design systems. The component shouldn't have any impact on this external space, because, bear in mind, the same problem applies to these layout components: they too have no idea of how or where they're going to be used. So if a layout component defines its margins only between its child components, then this won't impact its surrounding space, and we're all good to go.

[00:18:04] With those constraints set, it was time to scope out the project based on the work at hand. I talked to the designer in my team, explained what I was trying to do, and chose this piece of UI as the subject of our layout experiment. And look: he instinctively filled in that physical space, the space that was sitting between the components, which highlighted how space changed in relation to those components. And that got me thinking: what if we could make these layout components, which have the single responsibility of handling spacing, stay true to the spacing design tokens that exist within the design system? In other words, give the functionality that engineering wanted, but use the language of design.

[00:18:59] So this became our fourth constraint, to link us back to our design tokens: our layout components would only understand valid spacing tokens to set the size of the spacing that we wanted. Given we're using TypeScript, this was relatively easy to achieve, and it also gave us an extra safety net. If design provides us with an agreed set of spacing tokens, then we can guard against any rogue pixel sizes creeping into a layout.

The value of a shared language

[00:19:28] And that kind of brings us to the end of this spacing story. It's not anything groundbreaking. With those constraints set, we went on to build our box component, taking inspiration from Braid, and a stack component, taking inspiration from Every Layout. And of course, there is no end point with a design system. It's something that's constantly evolving. In fact, we're already revisiting those spacing design tokens to see if we can switch to an abstract naming convention after all. Maybe we can make it work this time, now that we've got a greater appreciation of the value of creating a shared language.

[00:20:09] Because when you start to work with a shared language, you have much better conversations with everyone. And we need that strong communication across teams if we want to foster better working relationships and encourage people to voice concerns or suggest new ideas. A design system is never done, and we need to encourage regular feedback to make sure that it keeps working for everyone who's using it. With a shared language, you get higher engagement. People stand a better chance of being heard and, more importantly, understood.

[00:20:44] It was surprisingly easy for me to get engagement on the layout components, present back to everyone and get buy-in when the work was done. Designers were engaged. They repeated it back to me: "Yes, of course, that's exactly how we see spacing." So I knew I'd made the right connection. They were excited to see the tokens actually being used in this way. And engineers were equally engaged, and this enabled them to share concerns that we could then address and work with.

[00:21:14] Ultimately, that better communication is going to bring about a greater understanding. I'm experiencing it in my own team and across product teams here at Zoopla, and I'm experiencing it between design and engineering. A design system can deliver huge benefits, but only if it can be understood by everyone. So I've got a final question for you. Are design systems hard, or is it how a company translates what the design system is that makes it hard for everyone working with it to understand? I'll leave you to interpret that one. Thank you for listening.

Speaker