Fully color space aware

Each color belongs to a color space; operations are color space agnostic. Modules for a wide variety of color spaces, including Lab/LCH, sRGB and friends (HSL/HSV/HWB), Display P3, Jzazbz, REC.2100 and 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.

Color.js is currently an unreleased work in progress. Here be dragons. If you found this website somehow, feel free to try it out and give us feedback, but sshhhh! 🤫 There are more bugs in the live code snippets ("Color Notebook") in the docs than the actual Color.js library, so before reporting a bug, please try to reproduce it outside Color Notebook.

Reading colors

Any color from CSS Color Level 4 should work:

			let color = new Color("slategray");
			let color2 = new Color("hwb(60 30% 40%)");
			let color3 = new Color("color(display-p3 0 1 0)");
			let color4 = new Color("lch(50% 80 30)");

			// CSS variables work too!
			let colorjsBlue = new Color("--color-blue");

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.lightness = 80; // LCH coords available directly on colors
			color.chroma *= 1.2; // saturate 20%
			color.hwb.whiteness += 10; // any other color space also available

Chaining-style modifications are also supported:

			let color = new Color("lch(50% 50 10)");
			color = color.set({
				hue: h => h + 180,
				chroma: 60

Read more about color manipulation

Converting between color spaces & stringifying

Output in any color space

			let color = new Color("slategray");
			color + ""; // default stringification
			color.to("p3").toString({precision: 3});

Clip to gamut or don't

			let color = new Color("p3", [0, 1, 0]);
			color.to("srgb").toString({inGamut: false})

Change color space:

			let color = new Color("slategray");
			color.space = "srgb"; // Convert to sRGB
			color.spaceId = "srgb"; // Same
			color.space = "sRGB"; // Capitalization doesn't matter
			color.space = Color.spaces.srgb; // Same
			color.spaceId = Color.spaces.srgb; // Same


Get a function that accepts a percentage:

			let color = new Color("p3", [0, 1, 0]);
			let redgreen = color.range("red", {
				space: "lch", // interpolation space
				outputSpace: "srgb"
			redgreen(.5); // midpoint

Interpolation by discrete steps:

			let color = new Color("p3", [0, 1, 0]);
			color.steps("red", {
				space: "lch",
				outputSpace: "srgb",
				maxDeltaE: 3, // max deltaE between consecutive steps
				steps: 10 // min number of steps

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