Skip to page content

Search powered by Pagefind.

Colors

color-mix(in OKLCH ... ) has been Baseline:widely available since March 2023 — all “evergreen” browsers (Chrome, Edge, Firefox, Safari) have capability to use it (see Can I use). Baselayer uses this function to set up a range of lightness levels for its built-in colors.

Rationale for Baselayer’s color system

I wanted to develop a color system based on interpolating CSS variables for generating a series lightness levels for each color, so that the stylesheet doesn’t need to be loaded with lighness classes for every color — most of which you’d never use.

After experimenting with variables in lightness channels within color codes, I discovered the new (mid-2023) color-mix() function. Using color-mix() is better suited to what I was trying to do. With it we can build a series of lightness levels by mixing in white (for tints) or black (for shades).

For usefulness in Baselayer CSS, starting color swatches need to have a mid-range lightness level, but they can be specified using any system (currently, Baselayer default colors are set using Hex # codes).

Blue Green Amber Red Gray
 
 
 
 
 

And the color-mix function now outputs colors in OKLCH using color-mix(in OKLCH ...) because this gives perceptually uniform lightness levels.

The color utility CSS class names remain the same as before (explained below). Example using background bg-* utility classes:

blue
100
200
300
400
500
600
700
800
900
green
100
200
300
400
500
600
700
800
900
amber
100
200
300
400
500
600
700
800
900
red
100
200
300
400
500
600
700
800
900
gray
100
200
300
400
500
600
700
800
900

Also available:

  1. A built-in dark theme.
  2. Black, white, and transparent — see other Baselayer color utilities.

Color and shade utility classes

All colors and lightness levels are declared in variables.css.

Color utility classes (declared in @layer color in colors.css) are prefixed acording to where the color will be applied — border b-* text t-* or background bg-*. I have named the colors according to their common names (blue, green, amber, red, gray). You can modify the root variables of these colors, and you can add your own colors.

Border Color Text Color Background Color
Default state Hover state Default state Hover state Default state Hover state
Lightness modifier b-100
...
b-900
hover:b-100
...
hover:b-900
t-100
...
t-900
hover:t-100
...
hover:t-900
bg-100
...
bg-900
hover:bg-100
...
hover:bg-900

Example border, text and background utilities:

b-green
t-green t-700 dark:t-300
bg-green bg-200
<div class="b-heavy b-green"></div>
<div class="t-heavy t-green t-700 dark:t-300"></div>
<div class="t-black bg-green bg-300"></div>

See also dark theme lightness levels and black, white, and reversi.

Example usage:

☆ Note (information) panel.
<div aria-label="Note" class="popout mt-3 mb-4 bl-heavy b-blue b-400 dark:b-600 p-3 t-reversi bg-blue bg-200 dark:bg-800">
  &star; Note (information) panel.
</div>

The lighness modifiers *-100 through *-900, if used alone, do not provide color. But if you use them to supplement one of the base colors above, then that color class will provide the color, and the modifier will set its lightness level.

Colors and accessibility

In any color model, color combinations must be chosen with care so that there is sufficient contrast between text and background colors for purposes of assessibility.

In your text and background color combinations, be careful to ensure that the text is readable — there needs to be an adequate contrast. Most organizations should to aim for WCAG level AA for accessibility requirements.

For WCAG level AA conformance, most user interface colors need to be darker than the mid-level (i.e. use *-600 up) if the text color is white, or lighter than the mid-level (i.e. use *-400 down) if the text color is black.

However, any colors near yellow such as Baselayer amber, as well as orange and yellow-green (not included), are especially difficult for accessibility. You may do better using a lighter background amber and pairing it with black text (or vise versa).

When colorizing buttons, remember to set their hover: hover state shades too.

<!-- Default button -->
<button type="button" name="button">Button</button>

<!-- Blue button -->
<button class="bg-blue bg-600 hover:bg-700" type="button" name="button">Button</button>

<!-- Amber button -->
<button class="t-black hover:t-black bg-amber bg-500 hover:bg-600" type="button" name="button">Button</button>

<!-- Green outline (a.k.a. ghost) button -->
<button class="b-thin b-green bg-transparent t-green t-600 hover:t-white hover:bg-green hover:bg-600" type="button" name="button">Button</button>

Background reading on colors and accessibility:

Adding more colors

You can, of course, add any colors you want, and in any format you want.

However, if you want to use Baselayer’s lightness modifier classes -100 thorugh -900 on your colors, then you need to start from a mid-lightness color so that the -100 and the -900 generated by the color-mix() formulas are distinguishable (not to chose to white or too close to black).

Also, you will need to put your color(s) in CSS layer @layer colors {} so that they take precence over the Baselayer lightness modifiers and other color utilities.

You can add your own project colors in any format, but the Baselayer color-mix() formulas will output shade in OKLCH format.

Examples:

:root {
  --purple: #9400d3;
  --teal: #0080A2;
}

@layer colors {
  .bg-purple {
    --bgc: var(--purple);
    background: var(--bgc);
  }
  .bg-teal {
    --bgc: var(--teal);
    background: var(--bgc);
  }
}

Dark theme

Baselayer has a simple dark theme built in. Since v.3.4.0, the user’s operating system preference for light or dark mode is automatically detected on the HTML tag:

html {
  color-scheme: light dark;
}

For the dark theme, HTML elements are generally flipped from light to dark, or dark to light, as required. The colors are as follows:

  • Body background is near black
  • Text is near white
  • Table borders, horizontal rules, form inputs are dark gray
  • Text links are a lighter blue
  • Default buttons are a lighter gray
  • Form elements’ text and background are switched the same as base text and body in dark mode

All the theme color variables in Baselayer (since v.3.4.0) involve a light-dark() CSS function. For example:

:root {
  /*
  Body tag background color
  */
  --bgc-body: light-dark(
    white,
    color-mix(in oklch, var(--gray), var(--l1000)));

  /*
  Base text color (also set on the body tag)
  */
  --tc-base: light-dark(
    color-mix(in OKLCH, var(--gray), var(--l900)),
    color-mix(in OKLCH, var(--gray), var(--l100))
  );
}

Baselayer does not use @media (prefers-color-scheme: dark) {} anywhere.

The color shade utilities can optionally be inverted by adding the *-dark-invert modifier classes.

Light and dark theme classes

If you wish to give your visitors the option to switch between light and dark modes, you can include a JavaScript that swaps between CSS classes theme-light and theme-dark on the HTML tag. Baselayer has these two tags built in, so that you can implement the style selection:

html {
  color-scheme: light dark;
  &.theme-light {
    color-scheme: light;
  }
  &.theme-dark {
    color-scheme: dark;
  }
}

Example implementation: the Baselayer documentation has demo JavaScript switches for light, dark, and auto modes. The auto mode removes theme-light and theme-dark from the <html> tag, so that you simply get the Baselayer default, that is the user’s operating system theme preference setting.

Dark theme lightness levels

There will be many situations in your design where you want your utility color shades darkened or lightened for the dark theme (similar to how the background color is flipped from white to near black, etc.). Since v.3.5, Baselayer has dark: prefixed color lightness utilities for border, text, and background colors. (This is more versatile versalility than the *-dark-invert modifier classes in v.3.4, that are now removed.)

Example using bg-blue:

<div class="bg-blue bg-100"></div>

<div class="bg-blue bg-100 dark:bg-900"></div>
Lightness utilities With dark mode
bg-100 dark:bg-900
bg-200 dark:bg-800
bg-300 dark:bg-700
bg-400 dark:bg-600
bg-500 dark:bg-500
bg-600 dark:bg-400
bg-700 dark:bg-300
bg-800 dark:bg-200
bg-900 dark:bg-100

Notes:

  • The middle dark mode dark:bg-500 is the same lightness level as its light mode counterpart.
  • The dark: prefix is only for switching lightness levels, not for switching colors.
  • When setting the hover state lightness level, the hover: prefix must come before the dark: prefix.
<!-- This is correct -->
<a href="" class="... hover:dark:bg-900">Link</a>

<!-- This will not work -->
<a href="" class="... dark:hover:bg-900">Link</a>

What if you don’t want a dark theme?

Then you can simply override or replace the HTML tag as follows:

html {
  color-scheme: light;
}

And you won’t need to use any dark: prefixed classes.

Other Baselayer color utilities

The color utilities for black, white, and transparent can’t be used on the same element with the colors and shades above (i.e. as either default or hover states). These other utilities are declared after the colors and shades, and so they will override them.

Other color utilities included in Baselayer cover black, white, and transparent.

Black, white, and reversi

Black and white are explicitly named colors in baselayer. They do not have lightness levels.

New in Baselayer v.3.5: If you want something black in the light theme but white in the dark theme (and vise versa), Baselayer has *-reversi and *-reversi-flip classes that handle this. See reversi.

  • *-black — named color black
  • *-white — named color white
  • *-reversi — black for light theme; white for dark theme
  • *-reversi-flip — white for light theme; black for dark theme
t-white
bg-black
t-black
bg-white
t-reversi-flip
bg-reversi
t-reversi
bg-reversi-flip
<div class="t-white bg-black">...</div>

<div class="t-black bg-white">...</div>

<div class="t-reversi-flip bg-reversi">...</div>

<div class="t-reversi bg-reversi-flip">...</div>

If you want “lightness levels” between white and black, then use grays.

Transparent background

E.g. for outline buttons.

  • Transparent: bg-transparent

There are no hover states of bg-transparent.