colors #

Color semantics
#

Moss provides a palette of color and hue variables designed to support concise authoring in light and dark modes, as well as straightforward theming by both developers and end-users at runtime. The colors have more semantics than just plain values, so they automatically adapt to dark mode and custom themes, at the cost of having different values depending on color scheme and theme.

Adapting colors to dark mode

A color's subjective appearance depends on the context in which it's viewed, especially the surrounding colors and values. Moss' semantic colors are designed to work across color schemes, so each Moss color variable has two values, one for light and one for dark mode. The exceptions are the lightest (1) and darkest (9) variants, although this may change if it yields better results.

Custom themes

Instead of "blue" and "red", colors are named with letters like "a" and "b", so you can change the primary "a" from blue to any color in a theme without breaking the name-to-color correspondence everywhere. This also flexibly handles more colors and cases than using names like "primary", and although it takes some learning, it's a simple pattern to remember. ("primary" and its ilk require learning too!)

A downside of this approach is that changing a color like the primary "a" affects the many places it's used. Sometimes you may want to change the color of a specific element or state, not all the things. In those cases, use plain CSS and optionally Moss variables. Compared to most libraries, Moss provides fewer handles for granular color customizations, but the benefits include consistency, efficiency, DRY authoring, and ease of app-wide theming.

Caveats
#

For performance reasons, Moss does not currently have an extensive set of variants, like specialized states for elements or color values like "blue". Each of the 7 hues has 9 HSL color values (e.g. hsl(120 55% 36%)) and 9 HSL values (e.g. 120 55% 36%, useful to apply custom alpha), handling most cases, and the base colors can be customized with platform APIs like the color-mix CSS function.

Variants will be expanded when Moss includes a Vite plugin or other build tooling for optimization. A downside of removing unused styles is that they won't be available to your end-users at runtime. We'll probably end up with an interpreted language like Tailwind's just-in-time compiler.

Hue variables
#

Hue variables contain a single hue number. Each color variable combines a hue variable with hardcoded saturation and lightness values for light and dark modes.

Hue variables therefore provide a single source of truth that's easy to theme, but to achieve pleasing results, setting the hue alone is not always sufficient. Custom colors will often require you to set per-variable saturation and lightness values.

Hue variables are also useful to construct custom colors not covered by the color variables. For example, Moss's base stylesheet uses hue_a for the semi-transparent ::selection. (try selecting some text - same hue!)

Unlike the color variables, the hue variables are the same in both light and dark modes.

  • NaN
    primary
  • NaN
    success/help
  • NaN
    error/danger
  • NaN
    secondary
  • NaN
    tertiary
  • NaN
    quaternary
  • NaN
    quinary
  • NaN
    senary
  • NaN
    septenary

Color variables
#

There are 9 variables per color, numbered 1 to 9, lightest to darkest. The 5th variable of each color is used as the base for things like buttons.

Note that these values differ between light and dark modes! See the discussion above for why.

These colors were eyeballed by a programmer, and will change :]

    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()
    • rgb()