Lessons learned — first 3 years building a design system
Things we learned when we built the City of Gothenburg’s design system and component framework
We hope you find our reflections useful and that they might keep you from repeating the same mistakes we did. At the very least, provide you with some comfort that you’re not alone if you did.
Early in the process we did several interface inventories together in the team.
Following Brad Frost’s instructions in the blog post Interface inventory we gathered around a Google drive presentation and a white board.
The sessions helped us to form a common picture of the current situation and it really got the conversation going about which components to create and how they relate to each other.
In the beginning, we spent much time and effort to discuss how to divide and name components according to the name conventions in Atomic design (Atoms, Molecules, Organisms).
Although, Atomic design is a useful way too think about modular design we later abandoned trying to categorize our components under each category.
We accepted that components can be of different sizes and that they sometimes are nested inside each other.
Visual style artifacts, like color palettes, typographic styles and icons are essential to a web site and sometimes easier to replace and harmonize than mark-up.
From the start, we jumped right in and started to create components. This meant we did not discuss and decide on basics like colors and typography early on. This was a mistake. With those things set, the details of each component’s design would have been a lot easier.
At the time, there was an uncertainty about who was responsible for the digital aspects of the city’s graphical profile. This was (or gave us) a reason to put these discussions on hold.
I recommend looking at the following three resources:
- Nathan Curtis’ article Color in design system
- Marcin Treders’s design system sprints blog series
- Shopify’s style guide and its Visuals part
The component library is home of the design system’s components. Bits of code serving a specific purpose that can be copied, combined and used in applications.
The idea to create a shared library of components for everyone to use is an easy concept to understand. The difficulty, we soon found out, is to decide which components to create. A bit naive, we clearly underestimated this part and the time it would take us to agree on and to create the right set of components.
We had endless discussions trying to reach a common understanding about which components to create, their purpose, how to classify them and how to name them. Looking back we spent to much time on theoretical discussions, instead of building and testing it out in the “real world”. We should have iterated the Think > Make > Check cycle far more often.
Some of these lengthy discussion would probably have been shortened or prevented if we had put more work into our component design guidelines from the start. More on the design guidelines topic below.
A website’s grid and its definitions are important to get right as it affects every page. Therefore the grid component deserves and needs special attention.
In our first iteration we decided on a robust and simple grid. It turned out it wasn’t flexible enough. Most problems were related to space. We didn’t have enough flexibility built in to adjust space between our rows and columns to fit the many different use cases we had.
We thought that if we reduced the possibilities and complexity, it would be easier to maintain over time but it turned we made it to simple and usability took a hit. The minimalist and stripped down design of the site was dependent on that we could use space effectively — and we couldn't.
The second iteration of our grid was made more flexible and gave us a possibility to control space (among other things) for each and every column separately. In the example below we can see the classes in bold that sets a different bottom-space on small, medium and large devices.
<div class="o-grid__column t-space-bottom-s t-space-bottom-m@m t-space-bottom-xl@l" data-size="4/4 4/8@m 6/12@l">
To be able to control the width of the grid-columns with the data-size attribute is something that I have found to be really effective. It is easy to use, to understand and to anticipate the effect of changes.
The below example shows how this grid column spans 4/4 columns on small devises, 4/8 on medium devices and 3/12 on large devices.
<div class="o-grid__column” data-size=”4/4 4/8@m 3/12@l”></div>
We also use the same notation (using CSS Flexbox) to modify the order of columns within the same grid on different devices. Below the second column will be shown after the first column on medium and large devices but first on small devices.
<div class=”o-grid__column” data-order=”2 1@m 1@l”></div>
<div class=”o-grid__column” data-order=”1 2@m 2@l”></div>
First we decided to use our own variation of the BEM naming convention.
Instead of using the standard terms Block, Element, Modifier and its syntax we used terms borrowed from Atomic design methodology. This meant our CSS classes had names referring to Atoms and Molecules with prefixes like a-button and m-slideshow.
I mentioned before that we adopted atomic design not only as a way of thinking but also as a way to categorize our components at first. The CSS naming convention we first came up with is also a result of this.
Even though we ended up with something that worked, it was a bit of a struggle and the source of constant debates about what should live where in the architecture.
Then Harry Roberts came and worked with us for a very intensive three day workshop. He introduced us to the ITCSS architecture that in combination with the BEM naming convention formed an architecture that was both easy to understand and had clear guidelines on where different CSS should live.
The day after the workshop ended we rewrote our CSS according to his recommendation and haven’t looked back since.
Design system templates
When we first started thinking about modular interface design we looked at what Lonely planet had done and their framework Rizzo. It was a template framework that made it possible to keep the component library in perfect sync with production code.
The idea is to build templates for the components that only include information about the content model, its values and perhaps attributes. Instead of having all your HTML markup scattered across your applications, the applications call the template which in turn generates the correct markup.
A change in markup would only need to be done in one place.
We could see all the benefits of this, especially since we had many applications maintained by a central team and most of them built with the same technical framework.
So, we started to develop a template framework that would fit us.
It would have been a big enough challenge to come up with the right components for the UI framework and its architecture, now we also had to simultaneously think about how a component or set of components should relate to our template layer.
My recommendation would be to first concentrate on building a UI framework and design system with everything that comes with it and then, after that, see if it is worth adding a template layer on top to get the added benefits it gives.
Nonetheless, we are still, with success, chasing the holy grail of design systems and continue to work on our component template framework.
A style guide is where you visualize the design system. One part is the component library where you present the components together with usage examples.
Initially we had no one using our design system and therefore no one else actually needed our style guide with documentation of our components. Still we decided to build one and make it publicly available. I believe this was important because having something tangible that others could see reinforced the feeling that we were building and developing a product. And that we needed to treat it like one.
Nowadays the style guide is a great resource and we use it to do acceptance testing, when we prototype applications and as a way to communicate what we do internally in the organisation.
One of the best thing we did so far was the Try-it yourself functionality that gives you the possibility to combine templates and, on the fly, evaluate the result in the browser.
For inspiration on style guides, check out Styleguides.io that has a large collection of publically avaliable style guides.
Guidelines and principles
During our initial work we talked a lot about guidelines and principles, but unfortunately we didn’t take the time to write them down. This meant everyone involved probably had a slightly different view of what they where.
I very much agree with Jared M. Spool and his views on great design principles.
“ Great design principles help designers learn more about their design and make critical decisions about what they’re building.” — Jared M. Spool
We we’re having the same discussions over and over, so eventually we decided to actually write down the guidelines to help us make decisions when creating our components.
Here they are together with a comment:
- Repetition is better than the wrong abstraction.
- If, for a component, you could easily apply the change with a modifier then it’s probably the same component, if it requires a lot of changes then it’s probably new component.
- Appearance and purpose can help determine if something is a new component or an extension of an existing. Ask yourself, are they just coincidentally similar now and how will they develop over time?
- If we change appearance of X on component A, do we expect that X should change also for component B and C — if so, they might be the same component.
- Don’t, at all cost, force everything into the design system. Infrequently used design patterns for complex artifacts can be left out.
- Give components abstract names. Avoid naming that indicates a specific use-case, e.g. “Snippet” rather than “Search result snippet”.
The first guideline, repetition is better than the wrong abstraction, deserves a comment since we fell into this trap a lot in the beginning.
We wanted to make everything DRY and in pursuit of this we missed that it should also be understandable for anyone outside our small circle (or to anyone of us a few weeks down the line).
Looking back, to sometimes accept repetition would have been the wiser choice.
Team and organization
Although vital to a design systems’s success, I would guess that this is an area that is often neglected. If the initiative to build a design system comes from the developer team there might be a tendency to focus on the more technical aspects of the system. For us, that was probably the case.
Fortunately, we had internal stakeholders that understood our goal and the implications of moving toward a central design system. Both its possibilities and limitations. Also they had patience with us and understood that there was initially a bigger effort needed before we could reap the benefits of the work.
During the first iteration, we piggy-backed on another large project. I would say that during this project we took the first steps. It was a good start and we learned a lot but we came nowhere close to where we are today.
With each following project we tried to develop and improve our system further. We also had budget and time allocated to the design system outside of projects. This was crucial for us to be able to move forward effectively.
We are now a small centralized team of 3–4 people working part time to maintain the design system.
Moving forward, as the use of the design system increases, we will definitely need to invest more time in this area. We will also need to formalize the processes of how we handle changes and requirements from stakeholders.
I recommend reading Designing a Systems Team by Nathan Curtis.
We started to think about a modular design approach in late 2013. A couple of months later we took the first steps. Now, almost 4 years later, I can say that it has been more work than we first anticipated but certainly worth it. We have seen so many positive effects and hope to continue the work over the years to come.
This was part 9 in the publication: Our Story: Building a component library