BLOG: How to build an effective design system with web components
In the Corporate Digital Design & UX team, we develop and improve Scania Digital Design System (SDDS), which enables a coherent and consistent user experience in different solutions throughout Scania's services and web applications. Beyond a collection of components or a set of patterns, the technical implementation is one of the most important cores to ensure the brand identity is well aligned across all the applications.
Web Components and Design System
To create components to be shared in a big organization like Scania, it is critical to make sure that the solution works regardless of the framework or platform that is used in the development process. That being the case, we found that Web Components is a suitable solution for the challenge as it uses web standards and does not need any other third-party libraries to use it. Therefore, it provides an efficient and robust way to deliver a set of reusable components in a web application.
The definition of Web Components according to MDN is:
Web Components is a suite of different technologies allowing you to create reusable custom elements — with their functionality encapsulated away from the rest of your code — and utilize them in your web apps.
The use of Web Components for design systems has become a common approach. In many corporations such as Spectrum from Adobe, IBM Carbon, EA, and Salesforce, this technology is used to deliver a set of reusable components. In spite of the fact that each company is using a different approach to develop web components, the results are the same, a component that offers an encapsulated function and styling that will work with modern web technologies and does not require other third-party libraries.
The main advantage of these features is that they can be used in any framework while keeping the quality and brand experience.
The Anatomy of Scania Digital Design System
The main features of Web Components include custom elements, shadow DOM, and HTML templates. The core technology we use in order to deliver SDDS is Stencil, a compiler for web components, created by Ionic.
Stencil generates standard web components that work in combination with any framework (such as Angular or React) or no framework at all. Since the Stencil API provides a lazy-loading feature that improves performance, we were able to move a lot of logic from the runtime to the compilation phase to optimize load time - this additional runtime logic was a drawback of the previous tool, Polymer.
This solution also enabled us to import components as a module and make web components available as self-contained components where the styling is scoped within the components.
Example of accordion component written in Stencil.JS
As you can see in the example above, Stencil uses different decorators such as @Prop, @Events, @Method to collect all the metadata of a component. These decorators are used for different features in a web component. For instance, @Prop is used to pass an attribute from the HTML to the component. We can also utilize the life-cycle methods to hook an operation in the right time. If you want to learn more, check Stencil API documentation.
By using web components with shadow-root set to true, the styling will also be encapsulated inside the component. It will not leak out to the HTML page, and it will not get the styling from outside. That is why we use CSS variables for the theme, so it is convenient when later we will have other theme options.
When it comes to flexibility, we strive to use slots instead of properties to allow users to add what they need to the components willingly. The <slot> element is part of the web components technology suite, it is basically a placeholder inside a web component that you can fill with your own markup, which lets you create separate DOM trees and present them together. For example, inside SDDS accordion components, developers might want to add a link or a paragraph with images and using slots makes it possible.
Styling slot element with CSS variable
When the implementation is done, we publish the components as a package in npm so anyone who wants to use SDDS can easily install it in their project. The components in the published package are available to be used in different frameworks such as Angular, React or Vue. Have a peek @scania/components to see the latest package!
An example of how to use SDDS component in a React
Challenges and Opportunities
Although web components seem to be an ideal solution to complement a design system, there are some challenges regarding technology that we used to create web components.
First, we are dwelling on how to extend a Stencil web component within another Stencil project. Through getting feedback from developers who consume our package, we found a case where a project wanted to develop their own Stencil web component by extending the SDDS component. It seems to be possible by doing a simple import, but it is still a gray area. We also know some cases where we have the same functionality that is used across different components.
Unfortunately, Stencil does not support inheritance, but it is possible to make it around by using composition where we embed a component within the other component’s render. The downside is that we need to rewrite all the properties and methods that we want to override.
On the other hand, enabling the option to import a component as an individual package is also a topic we discuss at length. Currently users import SDDS components as a bundle, yet there is a need of importing a component as a single bundle instead. If it is possible to import components separately, it can refine the developer experience and improve performance. Thankfully in Stencil's recent release, they introduced a feature called ‘dist-custom-elements’ to generate custom elements in a more optimized way for tree shaking. Since they recommended this approach when using any frontend framework integrations, we are considering adjusting the way in near future.
How we want to achieve a single component import in the future
The purpose of Scania design system is to secure a coherent and premium brand and user experience across all of Scania's digital touchpoints. To achieve this ambition, we needed to provide a solution that could work in any framework, any application. We believe using web components is the optimal path to reach the goal. Certainly it would face challenges, but the good news is that most of the technologies around web components are open source which means that communities are working together to improve the solution. Thus, there will be opportunities to solve the problems in one way or another.
Are you using web components? Or are you one of the developers using SDDS web components? Please share your thoughts around web components and design systems with us! You can find our work in Scania Digital Design System. Feel free to reach out at our repository or via firstname.lastname@example.org.
Here are some of gems to look into if you are interested in web components:
- Lit - Google's web components library, the core of which is a component base class designed to reduce boilerplate while providing reactive state, scoped styles, and a declarative template system.
- FAST - An web components library built by Microsoft which offers several packages to leverage depending on your project needs.
- Hybrids - Another open source web components library, which favors plain objects and pure functions over class and this syntax. It provides a simple and functional API for creating custom elements.