The _colors.scss file includes the CSS color variables and the color themes.

Unlike other CSS globals, creating a color system is 10% about coding and 90% about semantics.

In our framework, we use a "semantic" approach in naming the colors. For example, we don't use --blue and --red but --color-primary and --color-accent.

The color variables are organized in five groups:

  1. Main colors
  2. Feedback colors
  3. Color Contrasts
  4. Semantic colors
  5. Black + White

All color variables are defined using HSL color values. HSL stands for hue, saturation, and lightness. Once you set the base color, obtaining the tints and shades is easy: just modify the saturation and lightness percentages.

Main colors #

These are the "Brand" colors, mostly used for interactive elements (e.g., buttons). Each color in this section has 5 color variations (base color + 2 lighter versions + 2 darker versions).

:root, [data-theme="default"] {
    /* main */
    --color-primary-darker: hsl(220, 75%, 42%);
    --color-primary-dark: hsl(220, 80%, 48%);
    --color-primary: hsl(220, 90%, 56%);
    --color-primary-light: hsl(220, 90%, 63%);
    --color-primary-lighter: hsl(220, 90%, 92%);

    --color-accent-darker: hsl(355, 75%, 48%);
    --color-accent-dark: hsl(355, 80%, 54%);
    --color-accent: hsl(355, 90%, 61%);
    --color-accent-light: hsl(355, 90%, 68%);
    --color-accent-lighter: hsl(356, 89%, 93%);

Feedback #

Feedback colors are used to convey specific meanings like success/error/warning.

:root, [data-theme="default"] {
    /* feedback */
    --color-success-darker: hsl(94, 40%, 45%);
    --color-success-dark: hsl(94, 45%, 50%);
    --color-success: hsl(94, 48%, 56%);
    --color-success-light: hsl(94, 48%, 62%);
    --color-success-lighter: hsl(94, 48%, 92%);

    --color-error-darker: hsl(355, 75%, 48%);
    --color-error-dark: hsl(355, 80%, 54%);
    --color-error: hsl(355, 90%, 61%);
    --color-error-light: hsl(355, 90%, 68%);
    --color-error-lighter: hsl(356, 89%, 93%);

    --color-warning-darker: hsl(46, 90%, 50%);
    --color-warning-dark: hsl(46, 95%, 55%);
    --color-warning: hsl(46, 100%, 61%);
    --color-warning-light: hsl(46, 100%, 68%);
    --color-warning-lighter: hsl(46, 100%, 91%);

Color contrasts #

Creating a contrast scale means setting up the base for all your Themes. Think of color contrasts as neutral colors. In some cases, these are referred to as "greyscale" colors; but neutral colors are not always tints and shades of grey. For example, let's consider a component with a very dark background: it would make sense to use different shades of white (or different alpha values of white) as the neutral colors.

To create a scale of contrasts you need two starting colors: 1) background color and 2) highest contrast color. You can then generate stop colors in between, using tools like our app (We use Chroma.js to generate the contrast scale).

Color contrasts
Color Contrasts in CodyHouse Studio

The number of contrasts is limited to six to keep the whole system easy to maintain. While defining the scale, it helps to associate each color to an element of your UI:

If we consider a theme with a white background, then an example of the scale of contrasts could be the following:

Semantic colors #

These are the colors you want to store in variables for convenience (e.g., because you plan on editing them in different themes). A good example is the --color-border. You can assign to it a value from the contrast scale so that you won't need to remember which neutral color is being used for the borders when working on a component level.

:root, [data-theme="default"] {
    /* semantic */
    --color-border: var(--color-contrast-low);

.component {
    border: 1px solid var(--color-border);

Black + White #

Black and White represent the exception to the semantic rule. There's a reason for that: all the color variables can store different values according to the theme in use. But there can be cases where you want a color to remain the same, regardless of the theme. In 99% of the cases, the two colors you want to keep unchanged are black and white. This part can sound confusing now, but it'll make sense once you read the Themes section of this page.

:root, [data-theme="default"] {
    /* black + white */
    --color-black: hsl(240, 7%, 12%);
    --color-white: hsl(0, 0%, 100%);

Themes #

A theme is a group of colors that work together. Themes are generated by overwriting the CSS color variables defined in the starting theme. If you use the color variables properly in your components, it's amazing how easily you can switch from a "light" to a "dark" theme simply by applying a class.

We provide only the "default" theme in our framework, but you can easily take it as an example to build other themes. In the example below, you can take a look at how to create a new theme in the SCSS tab. By changing the data-theme value to one among default/dark/soft, you apply a different theme (the default theme is applied even if you don't specify the theme at all).

Now that you know how themes work, it should be clear why --color-black and --color-white don't follow the semantic rule. Considering the default theme in the example above, if you're working on a component level and want to set a white color that could change with the theme, then you should use --color-bg. While if you want a white color that is not affected by the theme, you should use --color-white.

Important: the background-color of the theme is, by default, equal to the --color-bg color contrast variable.

For example: if you need to set the background color of an element, you may want to use --color-bg, so that when the theme changes, that color is updated automatically. While if you're setting the color of the label of a button, you may need to use --color-white, so that if the theme changes but the background of the button remains the same, you won't risk the label color being updated and becoming unreadable.

Note: we use CSS variables and a gulp plugin to generate a fallback. However, themes other than the default one won't be visible in older browsers. That shouldn't be an issue because browsers that don't support CSS variables will still render the default theme (the content is accessible). More info on how to use CSS Variables in our globals docs page.

Opacity values #

The downside of using CSS Variables is that you can't combine them with SASS color functions. That means that if you need to set a specific opacity value in a component, you need to create a new variable in the _colors.scss file. The advantage of doing so is that you'll think twice before using new alpha values in your design system, forcing yourself to keep the system as simple as possible.

Here's an example of how to set a variable for a color with an opacity lower than 1:

:root, [data-theme="default"] {
    --color-primary: hsl(220, 90%, 56%);
    --color-primary-a80: hsla(220, 90%, 56%, 0.8);

We use cookies to give you the best possible website experience. By using CodyHouse, you agree to our Privacy Policy.