The idea
Colours that read on any background.
Tell huehash the background and the contrast you need. A colour you already have is made readable on it, and a name gets a colour that is. The same name always gets the same colour, and look-alikes are kept apart.
npm install huehash
From a name to a readable colour.
A name becomes a colour in five steps, and the last one is the one that matters: the colour is lightened or darkened until it reaches the contrast you asked for on your background. Nothing is looked up and nothing is stored, so the same name takes the same steps every time. Change the name and watch each step change with it.
Five promises
Contrast comes first, because a colour nobody can read is no use. The rest keep it the same, tell it apart, balance it and keep it clear. Each has a control, so you can try to break it.
Readable on every background you use.
A colour has to read on a dark page, a light one, a tinted panel and a hover state. Tell huehash which backgrounds and what contrast, and every colour meets it on all of them, lightened or darkened as each surface needs. The default is 7 to 1, which is WCAG AAA.
The same name always gets the same colour.
Once the backgrounds are set, the colour is worked out from the text and nothing else. There is no table to keep, nothing to sync between services, and nothing that shifts when someone adds a name. Your API, your app and your emails agree without ever talking to each other. Change the list and compare.
Look-alike colours keep a safe distance.
The colour wheel is finite, so colours cannot all be different. huehash keeps look-alikes a safe distance apart, in a line, in a grid or in a stack of grids. You choose how near counts as near, and how different counts as different.
No name shouts and no name fades.
Hues are not equally bright to the eye, so a plain hash to hsl() makes yellow glare and blue sink. huehash works in OKLCH, where lightness means what you see, and keeps every colour in one narrow band. These are the same 24 names both ways, measured on your surface.
Clear of the colours that already mean something.
Red, amber and green carry meaning in your interface. Name them once and huehash keeps every colour a set distance away from them, so a service never looks like a warning.
In real views
The same colours at work in the interfaces that need one for every name. Each view is drawn from huehash's real output on the surface you picked.
Under the hood
What it costs, what it exposes, and how to start.
Exact, small and fast.
The contrast you ask for is the contrast you get. No dependencies, no build step, and no surprises between releases.
The whole API.
Four functions cover most uses. The rest are there when you need them.
readable(color, options?)- A colour you already have, made readable on your backgrounds. Same hue.
colorFor(name, options?)- One colour for a name, as a hex string.
colorsFor(names, options?)- A colour for each name, with neighbours kept apart.
describeColor(name, options?)- The colour with its OKLCH values, CSS value, contrast and grade.
createHuehash(defaults?, { cacheSize? })- Your own defaults and your own cache.
avoidHuesOf(hexes, width?)- Hue ranges to keep clear of.
toCssVariables(colors)- CSS custom properties, ready to paste.
background- The surface or surfaces the colour sits on. Contrast is guaranteed against each.
minContrast- The WCAG ratio to guarantee. 7 by default.
avoid- Hue ranges to keep clear of.
mode- Force dark or light styling. By default it follows the background.
distance- The least gap between neighbours, in degrees.
colorsForonly. neighbours- How many items on each side count as neighbours.
colorsForonly.
Make a colour readable in a minute.
One function to fix a colour you have. Two more to colour names.
Bring your own colours.
Bring a brand colour or your own ids, labels and usernames to the playground, pick the backgrounds they must read on, and see them in real views before you write a line.