pattern of shifting hues to their 3-digit numbers, but the 4-digit numbers tend to become much less comprehensible.
The CSS font-weight
property shares a similar scale to that of Material Design. A lighter and thinner font weight starts at 100
, graduating in heaviness in 100-point increments until 900
. 400
maps to a normal weight, while 700
maps to a traditionally bold weight.
Font Weight | Meaning |
---|---|
100 | Thin |
200 | Extra Light |
300 | Light |
400 | Normal |
500 | Medium |
600 | Semi Bold |
700 | Bold |
800 | Extra Bold |
900 | Black |
CSS frameworks, such as Bootstrap and Foundation, tend to sidestep the problem by creating derivatives from primary colors using color functions. Relying on these functions, however, supposes that if the source color should change, the percentages of, e.g., lightness and darkness may need to be adjusted in turn. While it’s easy to keep colors as derivatives by using color variables, it can result in a problem in which there are too many derivatives, if they are managed locally instead of in a shared source file.
For example, rather than defining colors during their use:
You should centralize all color declarations:
Taking these exemplars into consideration, a new scale for codifying colors should support the following goals:
Supporting Goal #1 is accomplished with setting a number range. The range of 0
–1000
provides an abundant of initial possibilites, along with being consistent with Material Design and the font-weight
specification. This range could always be tightened later, as needed.
Material Design anchors its scale in the middle with primary colors, designated with a 500
marker. This approach supposes that color was perhaps chosen first, and then an evenly distributed series of tints and shades were subsequently derived. In order to support Goal #2, the primary source color should be able to reside anywhere along the range, not just the middle, and appropriate tints and shades could still be derived.
Similar to Material Design, the point along the scale should correspond to the lightness or darkness of a color. If 0
is always pure white (#fff
) and 1000
is always pure black (#000
), then to support Goal #3, the steps along the scale should roughly correspond to their equivalent lightness value.
Alas, lightness is a tricky subject that requires an understanding of color spaces to properly define it. Digital designers should be quite familiar with RGB, at least for the sake of using hexadecimal color values in CSS. Designers may also be familiar with another family of hue-saturation-* color spaces, which includes HSL (hue-saturation-lightness), HSV (hue-saturation-value), HSB (hue-saturation-brightness), and HSI (hue-saturation-intensity). These are attempts to represent the RGB model in a form that is easier to approach and reason about. While the lightness, value, brightness, and intensity values are easy to conceptualize, they ultimately are models describing how computers render color, and therefore, they’re insufficient to inform us how humans would perceive a given color. Colors may share identical lightness values, yet their perceived brightness is probably different. The Lab color space resolves this issue, given its L*
(lightness) value approximately corresponds to perceived brightness. A L*
value of 0
is the darkest black, while a value of 100
represents the brightest white.
The method for naming color variables will roughly follow the pattern Nicholas Gallager recommends for naming CSS classes:
Each color variable name consists of three parts:
color
to indicate the variable is a color;Put together, the template for a Less color variable name would follow this pattern:
In practice, we could describe an abbreviated color scale in this way:
Luckily, much of the difficulty of generating color scales is solved by the work of Gregor Aisch, as described in his article Mastering Multi-hued Color Scales with Chroma.js. He details how his Chroma.js JavaScript library can adjust complex multi-hue gradients to be both true to lightness values and pleasing to the eye.
Using Chroma.js, we can interpolate any color within our scale. For this example, the scale will be seeded with white, green, and black colors.
Bezier interpolation will ease the blending of the colors, while lightness correction will ensure a linear lightness progression throughout the scale. Run the following Node script to generate the nine-point color scale.
The color scale is generated as Less variables. However, with little tweaking, the output could be adapted as desired to better conform to other contexts.
For those desiring a visual editor rather than running a custom Node script, the Chroma.js Color Scale Helper tool is an excellent alternative to quickly experiment with various color scale configurations.
We demonstrated it is very possible to consistently devise color scales, linearly graduating from light to dark. By codifying the scale based on perceived brightness, we have a normalized way to compare colors across any scale, and it can simplify how we choose colors.
From here, there are several more tools and features that could be created to assist designers and developers interested in using codified color scales:
npm
package to codify color scales.