Colors

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.

Guide content:

  1. πŸ“How to use the colors of the Framework
  2. πŸš€How to use the Color Editor

How to use the colors of the framework #

In our framework, we use a "semantic" approach to 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

HSL color functions #

All color variables are defined using HSL color values. HSL stands for hue, saturation, and lightness. The great thing about HSL is that creating color variations is easy and intuitive: just modify the hue, saturation, and lightness of the starting color.

Each color is defined using the defineColorHSL mixin*. For example:

:root, [data-theme="default"] {
  @include defineColorHSL(--color-primary, 220, 90%, 56%);
}

*All the mixins are in the _mixins.scss global.

We use this SASS mixin to generate 3 CSS variables for each color (--color-name-h, --color-name-s, --color-name-l).

For example, in CSS you have:

:root, [data-theme="default"] {
  --color-primary: hsl(220, 90%, 56%);
  --color-primary-h: 220;
  --color-primary-s: 90%;
  --color-primary-l: 56%;
}

These variables allow us to combine SASS color functions and CSS Variables. For example, if you need to set an opacity value for a color, you can use the alpha color function:

.component {
  background-color: alpha(var(--color-primary), 0.2);
}

That in CSS compiles to:

.component {
  background-color: hsla(var(--color-primary-h), var(--color-primary-s), var(--color-primary-l), 0.2);
}

If you want to learn more about this method we've developed, you can check our article:

πŸ“How to combine color functions and CSS Variables.

⚠️ Important: there's a bug in Safari if you use a CSS Variable to set the opacity inside the box-shadow, border, text-shadow properties.

Specifically, the following code:

.component {
  box-shadow: 0 1px 3px hsla(var(--color-h), var(--color-s), var(--color-l), 0.2);
}

generates a black shadow even if the variables are correctly converted (if you check the computed style with the code inspector).

Therefore using the alpha function will generate the same issue:

.component {
  box-shadow: 0 1px 3px alpha(var(--color-black), 0.2);
}

This bug has been fixed in the upcoming Safari 12.2 version. In the meantime, a solution is to create a variable to store the alpha value of the color, and use that variable inside the property:

.component {
  --color-shadow: hsla(var(--color-black-h), var(--color-black-s), var(--color-black-l), 0.2); // fix iOS 12 bug
  box-shadow: 0 1px 4px var(--color-shadow);
}

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
  @include defineColorHSL(--color-primary-darker, 220, 90%, 36%);
  @include defineColorHSL(--color-primary-dark, 220, 90%, 46%);
  @include defineColorHSL(--color-primary, 220, 90%, 56%);
  @include defineColorHSL(--color-primary-light, 220, 90%, 66%);
  @include defineColorHSL(--color-primary-lighter, 220, 90%, 76%);

  @include defineColorHSL(--color-accent-darker, 355, 90%, 41%);
  @include defineColorHSL(--color-accent-dark, 355, 90%, 51%);
  @include defineColorHSL(--color-accent, 355, 90%, 61%);
  @include defineColorHSL(--color-accent-light, 355, 90%, 71%);
  @include defineColorHSL(--color-accent-lighter, 355, 90%, 81%);
}

Feedback #

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

:root, [data-theme="default"] {
  // feedback
  @include defineColorHSL(--color-success-darker, 94, 48%, 36%);
  @include defineColorHSL(--color-success-dark, 94, 48%, 46%);
  @include defineColorHSL(--color-success, 94, 48%, 56%);
  @include defineColorHSL(--color-success-light, 94, 48%, 66%);
  @include defineColorHSL(--color-success-lighter, 94, 48%, 76%);

  @include defineColorHSL(--color-error-darker, 355, 90%, 41%);
  @include defineColorHSL(--color-error-dark, 355, 90%, 51%);
  @include defineColorHSL(--color-error, 355, 90%, 61%);
  @include defineColorHSL(--color-error-light, 355, 90%, 71%);
  @include defineColorHSL(--color-error-lighter, 355, 90%, 81%);

  @include defineColorHSL(--color-warning-darker, 46, 100%, 41%);
  @include defineColorHSL(--color-warning-dark, 46, 100%, 51%);
  @include defineColorHSL(--color-warning, 46, 100%, 61%);
  @include defineColorHSL(--color-warning-light, 46, 100%, 71%);
  @include defineColorHSL(--color-warning-lighter, 46, 100%, 81%);
}

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 Color Editor (We use Chroma.js to generate the contrast scale).

Color contrasts
Color Editor

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 #

Optionally, you can include 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 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
  @include defineColorHSL(--color-black, 240, 8%, 12%);
  @include defineColorHSL(--color-white, 0, 0%, 100%);
}

Themes #

A theme is a group of related colors. The _colors.scss file of our framework includes a theme titled "default". To create a new theme, you need to make a copy of the default theme and overwrite the values of the CSS variables.

If you use the color variables properly (in particular, the color contrasts) in your components, it's amazing how easily you can switch from a "light" to a "dark" theme simply by applying a class.

πŸ‘‹pssst... we've created a tool that allows you to create and export color themes compatible with our framework: the Color Editor.

In the example below, you can take a look at how to create a new theme by inspecting the SCSS tab (feel free to skip the SASS functions. They are included in the _mixins.scss global file of the framework). 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 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.

How to use the Color Editor tool #

The Color Global Editor is a web design tool that generates color palettes and themes compatible with the CodyHouse Framework. You can use it to set the colors of your design system taking advantage of a visual approach, then copy the generated SCSS and replace the code of the _colors.scss file of the Framework.

βœ… When you save your changes, all the colors inside the components are updated with the style you set in the Editor.