Color.js: Let’s get serious about color
Features:
- Color space agnostic: Each color object is basically a list of coords and a color space reference. Operations are color space agnostic.
Modules for a wide variety of color spaces,
including Lab/LCh, OKLab/OKLCh,
sRGB and friends (HSL/HSV/HWB), Display P3,
Jzazbz, REC.2100 and many more.
- Doesn't gloss over color science: Actual gamut mapping instead of naïve clipping,
multiple DeltaE methods (76, CMC, 2000, Jz),
multiple chromatic adaptation methods (von Kries, Bradford, CAT02, CAT16),
all with sensible defaults
- Up to date with CSS Color 4: Every CSS Color 4 format & color space supported for both input and output, whether your browser supports it or not.
- Readable, object-oriented API: Color objects for multiple operations on the same color, and static
Color.something()
functions for one-off calculations - Modular & Extensible: Use only what you need, or a bundle. Client-side or Node. Deep extensibility with hooks.
- Fast & efficient: Procedural, tree-shakeable API available for performance sensitive tasks and reduced bundle size
Installation
Install via npm:
npm install colorjs.io
For quick experiments, you can just import Color.js directly from the CDN with all modules included:
import Color from "https://colorjs.io/dist/color.js";
You can also import specific modules:
import Color from "https://colorjs.io/src/color.js";
import p3 from "https://colorjs.io/src/spaces/p3.js";
import rec2020 from "https://colorjs.io/src/spaces/rec2020.js";
import deltaE200 from "https://colorjs.io/src/deltaE/deltaE2000.js";
Warning: To use import
statements in a browser, your <script>
needs type="module"
Or, if you'd rather just have Color
as a global variable, the classic way, just include the following script in your HTML:
<script src="https://colorjs.io/dist/color.global.js"></script>
Read more about installation
Reading colors
Any color from CSS Color Level 4 should work:
let color = new Color("slategray");
let color2 = new Color("hwb(60 30% 40% / .5)");
let color3 = new Color("color(display-p3 0 1 0 / .9)");
let color4 = new Color("lch(50% 80 30)");
You can also create Color
objects manually:
let color2 = new Color("hwb", [60, 30, 40], .5);
let color3 = new Color({space: "p3", coords: [0, 1, 0], alpha: .9});
Read more about color objects
Manipulating colors
You can use properties to modify coordinates
of any color space and convert back
let color = new Color("slategray");
color.lch.l = 80;
color.lch.c *= 1.2;
color.hwb.w += 10;
To modify coordinates in any color space you use color.set()
and color.setAll()
:
let color = new Color("slategray");
color.set({
"lch.l": 80,
"lch.c": c => c * 1.2
});
color.set("hwb.w", w => w + 10);
Coordinates of the color's color space are available without a prefix:
let color = new Color("slategray").to("lch");
color.set({
l: 80,
c: c => c * 1.2
});
color.set("h", 30);
Chaining-style modifications are also supported:
let color = new Color("lch(50% 50 10)");
color = color.set({
h: h => h + 180,
c: 60
}).lighten();
You can also use properties:
let color = new Color("slategray");
color.lch.l = 80;
color.lch.c *= 1.2;
color.hwb.w += 10;
Coordinates of the color's color space are available without a prefix:
let color = new Color("slategray").to("lch");
color.l = 80;
color.c *= 1.2;
Read more about color manipulation
Converting between color spaces & stringifying
Convert to any color space:
let color = new Color("slategray");
color.to("lch")
Output in any color space
let color = new Color("slategray");
color + "";
color.to("p3").toString({precision: 3});
Clip to gamut or don't
let color = new Color("p3", [0, 1, 0]);
color.to("srgb") + "";
color.to("srgb").toString({inGamut: false});
Read more about output
Interpolation
Get a function that accepts a percentage:
let color = new Color("p3", [0, 1, 0]);
let redgreen = color.range("red", {
space: "lch",
outputSpace: "srgb"
});
redgreen(.5);
Interpolation by discrete steps:
let color = new Color("p3", [0, 1, 0]);
color.steps("red", {
space: "lch",
outputSpace: "srgb",
maxDeltaE: 3,
steps: 10
});
Shortcut for specific points in the range:
let color = new Color("p3", [0, 1, 0]);
let redgreen = color.mix("red", .5, {space: "lch", outputSpace: "srgb"});
let reddishGreen = color.mix("red", .25, {space: "lch", outputSpace: "srgb"});
Static syntax (every color method has a static one too):
Color.mix("color(display-p3 0 1 0)", "red", .5);
Read more about interpolation