Not so long ago, user interfaces for the web were built mostly using standard HTML and CSS. The rise of frameworks such as React, Vue, Angular and Polymer made it possible to wrap and re-use UI components across parts of the same application or even between products.
Components found their perfect match with Design Systems, and allowed them to evolve from style guides or reference style sheets to full-blown libraries with modular assets containing Application Programming Interfaces (APIs) for setting a component’s appearance, content and behaviour.
1. Components vs. CSS-Only
Design systems can be implemented as component libraries or CSS-only stylesheets. While both have their pros and cons, in this post I will focus on the component-based approach.
Among the many advantages of using components over CSS-only libraries, these are the ones I consider the most valuable:
Design can be kept consistent by only exposing the parts which are supposed to be customised.
Product code becomes easier to read and maintain through the encapsulation of logic, styles and markup inside components.
Conflicting class names and other definitions can be avoided since they are isolated inside the component’s scope.
As an example, let us take a look at Material Design’s button implemented both ways. If only label, icon and type are customisable, a component approach only exposes the necessary APIs while a CSS-only approach exposes all the complexity:
2. Why should designers care?
Since APIs are not visible to the final users, it may not be clear why UX designers should be involved in designing them.
Components are first assembled by product teams before reaching the final users, and the API is the main interface between a component and product designers or developers consuming it. From this perspective, developers and designers are the first users of a Design System and their experience should be considered as well.
A well designed API will increase the developer’s experience, reducing the risk that they will implement their own solutions and therefore increasing productivity and enhancing the consistency of the final product.
3. Factors to consider
When designing a component and its corresponding API, some key factors should be considered to ensure they are easy to consume, consistent with the rest of the system, and easy to scale and maintain in the future.
a) Which variations should be offered?
With an overview of all possible use cases, designers can help define which parts of a component should be customisable through the use of properties and which should be kept stable, avoiding unwanted variations and therefore enhancing design consistency.
On the image below, label and icon are customisable, while icon-color and removable are not designed to be changed.
—
b) Which styles should be customisable?
Since consumers do not have access to the encapsulated content, customising styles can only be done through APIs.
CSS variables can be used for changing single css values (e.g. --border-radius). In case multiple styles should be changed together for a given variation (e.g. alert type changing icon color and font size) a property could be used instead.
Variables can be defined as a global theme (e.g. --accent-color) and modified for a single component, or new variables can be defined only for a given component (e.g. --footer-padding)
—
c) How will the component evolve in the future?
Components and their APIs evolve over time as new use cases arise. For this reason, they should be designed for change, based on facts or forecasts of how use cases may evolve.
An API that is not designed with evolution in mind will likely result in breaking changes when new use cases come up.
On the image below, the warning variation of the dialog could be defined as a warning boolean prop, but if error or success use cases are expected to come up in the future, it could instead be defined as a type="warning" string prop.
—
d) Which parts can be isolated?
Complex components are hard to consume. To simplify a component’s API, it is good practice to isolate smaller, reusable elements.
These elements can be wrapped inside the parent component or manually added by the consumer as child elements, depending on the amount of variation expected (see paragraph about slots below).
—
e) Where can content be inserted?
Not all functionalities of a component need to be pre-defined and offered through specific APIs.
For use cases that require more flexibility, consumers should be able to insert custom content inside pre-defined slots (AKA portals, containers or children areas).
Slots can define how its children elements will appear (e.g. from top to bottom or left to right, with 8px space between them), but the consumers have full control over the style of the inserted elements, since they are not encapsulated.
Conclusion
While it is extremely important that components are easy to use for the final users, developers and designers should be considered first-hand users of Design Systems and component libraries, and designing APIs that are easy to consume will significantly improve their experience.
Designers that understand how components API work can make more meaningful decisions when defining a component, and this will enhance the communication with developers as well.
Top comments (9)
It'd be nice if React had slots, it's one of the things I missed when moving over from Polymer. Very good article thank you for writing it. I hadn't thought to include a designer in the component making process but it makes sense especially when it comes to future planning to avoid breaking changes.
I agree, slots offer a good balance of control and flexibility and I am happy most frameworks support it (or an equivalent). I hope React will catch up on that.
Is there one tool to help us do what you describe in this article? It was eye-opening to someone just reading up on components.
Hi, are you interested in a tool for implementing component APIs or for designing them?
Both actually, but first step would be creating them. That’s where I’d like to start. I have an app I’d like to build. As a designer, I can see the benefits of components.
Bootstrap and React: we're about to end this man's whole career
😬
I like how you broke this down and built up a simple component into something more scalable and future-proof. Thanks for sharing!
Thank you so much 😊