Back to overview

Themes, Vol. 1 (introduction to styles scalability)

7 jun 202315 min. read

Hello there! 👋 This is the first of a series of articles that I'll be talking about themes. In this first edition I want to focus mainly on the concept and the mental model behind a theme.

We are going to talk about what is, what it is used for, pros and cons, and when we should use it so let's start with the first question:


What's a theme?

We can think about a theme as our source of truth of styles, a contract in which we define all the visual and atomic properties that will determine the look and feel of our user interface (like colors, typography, shadows, etc)

Having a theme model helps us to have a visual consistency throughout our application and more control over the styles. Let's see a basic example of what a theme implementation would look like in a .jsx file (please, don't do this at home, it's just an example):

theme.js
Button.jsx

_11
export const theme = {
_11
colors: {
_11
primary: '#cdb4db',
_11
secondary: '#ffc8dd',
_11
acent: '#a2d2ff',
_11
},
_11
borders: {
_11
sm: 4,
_11
md: 8,
_11
},
_11
}

Now, imagine that you're using the theme in every component and wanted to update the colors in the entire application, we only have to update one thing: our theme

Why It's important a theme?

More and more complex user interfaces are being built and as an application grows, it can be a challenge to maintain or evolve its styles. That's where themes come in to offer us:

  1. Scalability: we can add new parameters or changes (enriching or cutting out) to the main structure throughout the application.

  2. Flexibility: having an user interface based on themes, we can have more than one theme, for more than one need (like dark and light mode).

  3. Consistency: unified standards and criteria throughout the application. We can significantly reduce the loose definitions.

  4. Maintainability: updates of colors, scales and changes in one place.

Disadvantages of having a theme

Yes, there are many benefits but let's remember that everything has its cost and implementing a theme is no exception because it can represent a cost of time or effort and sometimes, a challenge. These are some of the disadvantages we may have to deal with:

Time: In a real world scenario with an interdisciplinary team, a theme requires coordination with the design team and sometimes the creation of a design system or a UI KIT. And both design, coordination and then development can take a vital time in delivering value to a product or its business model. (once we have a theme then, changes or updates to the UI are incredibly fast, I will take into account the initial time cost of implementation).

Complexity: Depending on the need of the product, we will need to think about the architecture of styles of our user interface and come up with the most suitable approach or solution.

Integration of technologies: If we are not using any framework-ui in our application, we should consider integrating some tool, because if we need a theme a little more complex than the definitions provided by CSS Custom properties or updates in a "programmatic" way then, we will need some extra help. Some options are the CSS in JS styling ways, however we must be very careful because many options come with a performance cost at runtime, however there are alternatives such as Vanilla Extract or Panda-CSS that already solve this aspect but makes your styles a bit complex (and powerful!). There's a trade-off that you have to take

When shoul I use a theme?

Just as everything has its use case, the theme model is no exception. Although the most common motivation for incorporating a theme (at least with CSS properties), is having a "white or dark mode", here are some reasons to know if you need to implement a more complex theme model in your application:

  1. If your application has a medium/large volume of UI components and depends a lot on its look and feel.
  2. If your application needs to update periodically or by events/seasons its identity.
  3. If you are creating a component library based on some design system (especially this point).
  4. If your users can change and customize color preferences or appearance of your application.

When it would not be necessary to implement a theme?

If your application has a small volume of UI components or a simple user interface or even if you are developing a prototype/demo and you need to go really fast.

While the points mentioned above can help us make a decision on whether or not to include a theme in our UI architecture, they are not absolute reasons. It will depend a lot on the needs of your application, its size, or if you are already using any framework-ui (tailwind-css, material-ui, etc).

Different flavours

Of course it is not the same to create a theme for an entire design system, than to use a theme model in a small/medium application to standardize the measures and primitive units of your application. So I would like to make a distinction between two model types:

Partial Themes, based on CSS Custom Properties

It's hard to talk about themes without mentioning CSS custom properties. They are incredibly useful but have their limitations with what we can declare. They still can't cover all the needs involved in complex theming throughout an application. However for the most general cases, they usually cover the needs of a basic theme.

Themes based on CSS in JS

Vanilla Extract | Panda CSS | TypeStyle | Styled Components

With CSS in JS themes we can define a more complex structure of styles and properties based on structures like objects, arrays, etc or any structure that we need. Every library can implement the theme model by different ways but every one of them has the same goal: to provide a theme model that is scalable, flexible and maintainable.

What else should I know?

It is important to mention that in a "real world" and interdisciplinary environment, in order to successfully implement a theme in our application, there must be a coordination and preparation with the design team. They are the ones in charge of the look and feel of the application. Together with them, we will be able to define the scope and complexity of the theme for our UI architecture.

Conclusions

In conclusion, implementing a theme in a user interface can be an expensive task that requires coordination, time and careful consideration of the UI architecture. However the benefits we gain often outweigh the disadvantages by ensuring visual consistency, providing scalability, flexibility and maintainability of styles in our application.

Let's recall the use case: if your application has a large volume of visual components or if your application needs to update its identity periodically or programmatically due to events or user preferences.

So, what can we learn about themes?

Although we will not always need to implement a theme using CSS in JS technologies, we can strive for standardized styles and take advantage of themes even without their explicit implementation (for example the importance of using CSS Custom Propperties or the composition of atomic components over specific style definitions):


_11
/* better this */
_11
.btn {
_11
backgorund-color: var(--color-primary);
_11
border-radius: var(--border-sm);
_11
}
_11
_11
/* over this */
_11
.btn {
_11
backgorund-color: #cdb4db;
_11
border-radius: 8px;
_11
}


_10
/* better this */
_10
const Button = () => (
_10
<button style={{ backgroundColor: theme.colors.primary, borderRadius: theme.borders.md }}>Hello!</button>
_10
)
_10
_10
/* over this */
_10
const Button = () => <button style={{ backgroundColor: '#cdb4db', borderRadius: '12px' }}>Hello!</button>


I hope it has helped you understand what a theme is and why it is important in our user interfaces. In the next sections we are going to be talking more in deep about how to build effective themes.