Skip to main content
Default Gray Amethyst

Themes

Modes UI offers a default light and dark theme along with some fine-tuned themes (color palettes) based on our highlight colors that you can try out on this documentation page.

A theme is nothing more than a stylesheet that uses the Modes UI token naming convention to define design tokens and apply custom styles to components. To create a theme, you will need a basic understanding of CSS, including CSS Custom Properties

Theme basics

All themes are scoped to classes using the mo-theme-{name} convention, where {name} is a lowercase, hyphen-delimited value representing the name of the theme. The included light and dark themes use mo-theme-default-light and mo-theme-default-dark, respectively. A custom theme called “Amethyst”, for example, would use a class called mo-theme-amethyst-light and mo-theme-amethyst-dark, respectively.

All selectors must be scoped to the theme’s class to ensure interoperability with other themes. You should also scope them to :host so they can be imported and applied to custom element shadow roots.

:host,
.mo-theme-amethyst-light {
  /* ... */
}

Activating themes

To activate a theme, import it and apply the theme’s class to the <html> element. This example imports and activates the built-in dark theme.

<html class="mo-theme-default-dark">
  <head>
    <link rel="stylesheet" href="path/to/modes-web-components/themes/dark.css" />
  </head>

  <body>
    ...
  </body>
</html>

Using non-default themes

You should always import the default theme variant that you need. If you want to allow the users to choose between the two options, you will have to import both light and dark default themes. These default theme files include a lot of token variable definitions and the default color definitions that are required for all the components to function as intended. If you want to add more color to your application, you must add the new color scheme on top of the existing default theme (light or dark).

If you want your theme color scheme to work for both light and dark mode, you’ll have to create two separate theme files to apply based on the mode the user has selected. In the dark theme the color scheme (shades) will have to be inverted to create the same contrast with a black background. You can find examples of this in the creating themes section.

<html>
  <head>
    <link rel="stylesheet" href="path/to/modes-web-components/themes/light.css" />
    <link rel="stylesheet" href="path/to/modes-web-components/themes/dark.css" />
    <link rel="stylesheet" href="path/to/modes-web-components/themes/my-custom-theme.css" />
  </head>

  <body>
    ...
  </body>
</html>

It’s for this reason that themes must be scoped to specific classes.

Gray theme

Modes UI comes with the gray theme, which is a lower contrast variation of the default theme. It is enabled the same way other custom themes are enabled, and it is an extension to the default themes.

<html>
  <head>
    <link rel="stylesheet" href="path/to/modes-web-components/themes/light.css" />
    <link rel="stylesheet" href="path/to/modes-web-components/themes/dark.css" />
    <link rel="stylesheet" href="path/to/modes-web-components/themes/gray.css" />
    <link rel="stylesheet" href="path/to/modes-web-components/themes/gray-dark.css" />
  </head>

  <body>
    ...
  </body>
</html>

Once the theme is imported, enable it by applying the class mo-theme-gray-light (and mo-theme-gray-dark depending on theme) to the root html element in the DOM.

Creating themes

The way you create a new theme in Modes UI is by creating a new color scheme. This color scheme is essentially built from the different shades of one color for now, as the library is monochrome. You need to provide a shade palette with specific token names, that the components will then use instead of the default ones. If these tokens are misnamed or otherwise broken, the components will fallback to the default theme values.

Here’s an example of the Amethyst theme files that are offered in the library:

:host,
html[class*='amethyst'] {
  --mo-color-primary-0: #000000;
  --mo-color-primary-10: #250059;
  --mo-color-primary-20: #3f0689;
  --mo-color-primary-25: #4a1b94;
  --mo-color-primary-30: #562ba0;
  --mo-color-primary-35: #6239ad;
  --mo-color-primary-40: #6e46ba;
  --mo-color-primary-50: #8860d5;
  --mo-color-primary-60: #a37af1;
  --mo-color-primary-70: #bc99ff;
  --mo-color-primary-80: #d3bbff;
  --mo-color-primary-90: #ebddff;
  --mo-color-primary-95: #f7edff;
  --mo-color-primary-98: #fef7ff;
  --mo-color-primary-99: #fffbff;
  --mo-color-primary-100: #ffffff;
}
:host,
html[class*='amethyst-dark'] {
  --mo-color-primary-0: #ffffff;
  --mo-color-primary-10: #ebddff;
  --mo-color-primary-20: #d3bbff;
  --mo-color-primary-25: #c7aaff;
  --mo-color-primary-30: #bc99ff;
  --mo-color-primary-35: #b088ff;
  --mo-color-primary-40: #a37af1;
  --mo-color-primary-50: #8860d5;
  --mo-color-primary-60: #6e46ba;
  --mo-color-primary-70: #562ba0;
  --mo-color-primary-80: #3f0689;
  --mo-color-primary-90: #250059;
  --mo-color-primary-95: #18003f;
  --mo-color-primary-98: #0c0026;
  --mo-color-primary-99: #060019;
  --mo-color-primary-100: #000000;
}

You can find these pre-defined themes/color schemes in the themes folder alongside the default ones. They offer examples on what is a good color scheme in terms of shades, and how to invert the colors for the use of the dark mode variant.

Dark theme

The built-in dark theme uses an inverted color scale so, if you’re using design tokens as intended, you’ll get dark mode for free. While this isn’t the same as a professionally curated dark theme, it provides an excellent baseline for one and you’re encouraged to customize it depending on your needs.

The dark theme works by taking the light theme’s color tokens and “flipping” the scale so 10 becomes 90, 20 becomes 80, 30 becomes 70, etc. Next, the luminance of each primitive was fine-tuned to avoid true black, which is often undesirable in dark themes, and provide a richer experience. The result is a custom dark palette that complements the light theme and makes it easy to offer light and dark modes with minimal effort.

To install the dark theme, add the following to the <head> section of your page.

<link rel="stylesheet" href="path/to/modes-web-components/themes/dark.css" />

To activate the theme, apply the mo-theme-default-dark class to the <html> element.

<html class="mo-theme-default-dark">
  ...
</html>

Detecting the user’s color scheme preference

Modes UI doesn’t try to auto-detect the user’s light/dark mode preference (except on the documentation page). This should be done at the application level. As a best practice, to provide a dark theme in your app, you should:

  • Check for prefers-color-scheme and use its value by default
  • Allow the user to override the setting in your app
  • Remember the user’s preference and restore it on subsequent logins

Avoid using the prefers-color-scheme media query because not all apps support dark mode, and it would break things for the ones that don’t.