Skip to content

Instantly share code, notes, and snippets.

@sandgraham
Created August 22, 2019 02:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sandgraham/69ace43ac73c31efe3ea3989e3c10868 to your computer and use it in GitHub Desktop.
Save sandgraham/69ace43ac73c31efe3ea3989e3c10868 to your computer and use it in GitHub Desktop.
Randoms thoughts on theme systems

Themes

A theme is the static configuration of a theme-able system. This requires a way to express the configuration and a theme-able system that is responsible for using the configuration to apply the expected styling.

I would argue that a good theme system has two key properties:

Interface

The interface consists of high level semantic variables that can be reused. This is where you assign values to variables such as primary, accent, etc. This is a convenient abstraction over specific assignments of values to style properties. It makes it easy to quickly customize a system with a different set of tokens.

Assignment

At some point you need to decide what a style property should be. Assignment is the baseline for a theme. If we consider a theme to be a "static configuration of a theme-able system", the set of our assignments is equivalent to the theme itself.

// button source code
<button style={{backgroundColor: '#000'}} />

Ideally we can use semantic variables from our theme interface.

// theme config
const $theme = {
  primary: '#000',
};

// button source code
<button style={{backgroundColor: $theme.primary}} />;

In this approach, you have hard-coded a single mapping of semantic variables to assignments. That is, button will always use the primary variable. But what if someone wants to use an alternate mapping? Let's say they want to use their accent variable for the button background?

// theme config
const $theme = {
  primary: '#000',
  accent: '#00F',
};

const $map = {
  buttonBackgroundColor: $theme.primary,
};

// button source code
<button style={{backgroundColor: $map.buttonBackgroundColor}} />;

Here we are introducing an intermediary layer for mapping semantic theme variables to the actual style property assignment. This allows us to create alternate theme mappings:

// this project wants to use the accent color for buttons
const $map = {
  buttonBackgroundColor: $theme.accent,
};

This makes our theme system more flexible but brings up an important question: Should we allow for alternate mappings in our theme system? If we are okay with having one mapping hard-coded than we don't require this layer of configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment