Color Memory Game
By John K.··15 min read

Shades of gray: 51 names, hex codes, and the color that is not actually neutral

Every named shade of gray with its hex code, measured in CIELAB and compared pairwise with CIEDE2000. Only 21 of 51 named grays are truly neutral, the tinted ones lean blue by 17 to 9, and sRGB's 256 gray codes contain about 67 your eye can actually separate.

Gray is the color defined by subtraction. Red is a hue, blue is a hue, but gray is what you get when you take the hue out and leave only the lightness behind. Every definition you will find says some version of that: gray is the neutral axis, the line running from black to white with no color on it at all.

So I measured the gray vocabulary expecting a list of neutrals, and got something else. Of the 51 named grays with a settled hex value, 21 sit exactly on the neutral axis. The other 30 carry a measurable tint. That much I expected. What I did not expect was the direction. Among the tinted names, the ones leaning blue outnumber the ones leaning yellow 17 to 9, and when they lean blue they lean roughly twice as hard: mean chroma 7.13 on the cool side against 3.52 on the warm side.

Average the whole set on the blue-yellow axis and it lands at b* of negative 1.74. Not zero. English does not really have a word for colorless. It has a word for slightly blue.

This is the same measurement I ran on the reds, the oranges, the yellows, the greens, the blues, the purples, the pinks and the browns. Every one of those families is a hue with names attached to it. Gray is the only one that claims to be no hue at all, which makes it the only one where the measurement can catch the vocabulary in a contradiction. It did.

The 51 named grays, dark to light, with hex codes

Sorted by CIELAB lightness in five bands, darkest first. L* is lightness on a 0 to 100 scale, C* is chroma, and hue is the CIELAB hue angle in degrees. For orientation on those hue angles: pure sRGB blue sits at 306.3, cyan at 196.4, green at 136.0, yellow at 102.9 and red at 40.0. Anything in the 180 to 300 range is on the cool side of the wheel. Chroma below about 0.5 is neutral for practical purposes, so those entries have no meaningful hue to report.

Near black, below L* 30

Nine names. This band is where gray hands off to black, and the handoff is not clean. Four of these nine read as blue-gray rather than gray, and charcoal is nearly as tinted as some named blues.

  • Black, #000000. L* 0.0, C* 0.0. The anchor. Whether it counts as a color at all is a longer argument.
  • Eerie black, #1b1b1b. L* 9.8, C* 0.0.
  • Raisin black, #242124. L* 13.2, C* 2.6, hue 324.8.
  • Anthracite, #293133. L* 19.7, C* 3.8, hue 220.0. Named after the hardest grade of coal.
  • Gunmetal, #2a3439. L* 21.0, C* 5.4, hue 238.0.
  • Jet, #343434. L* 21.7, C* 0.0. Perfectly neutral, and named after fossilised wood.
  • Onyx, #353839. L* 23.3, C* 1.5, hue 225.7.
  • Black olive, #3b3c36. L* 25.0, C* 4.0, hue 116.1. The only warm-leaning name in the band.
  • Charcoal, #36454f. L* 28.4, C* 8.6, hue 247.8. Burnt wood is not blue. The hex code everyone standardised on is.

Dark mid, L* 30 to 50

Nine names, and the widest chroma spread of any band. Davy's gray and dim gray are dead neutral while Payne's gray and dark slate gray sit at chroma 12, which is more color than some named browns carry.

  • Outer space, #414a4c. L* 30.7, C* 4.0, hue 217.7.
  • Dark slate gray, #2f4f4f. L* 31.3, C* 12.3, hue 197.6. A CSS keyword, and effectively a dark teal.
  • Dark liver, #534b4f. L* 32.8, C* 4.3, hue 344.4.
  • Graphite, #594d5b. L* 34.4, C* 10.1, hue 321.2. The only strongly violet name in the set.
  • Davy's gray, #555555. L* 36.1, C* 0.0. Named for Henry Davy, and one of the few gray names that is genuinely a pigment rather than a metaphor.
  • Payne's gray, #536878. L* 42.9, C* 12.1, hue 252.0. Watercolorists have known this one is blue for two centuries. It was mixed as a substitute for black precisely because it is not neutral.
  • Dim gray, #696969. L* 44.4, C* 0.0. A CSS keyword.
  • Nickel, #727472. L* 48.6, C* 1.4, hue 144.4.
  • Sonic silver, #757575. L* 49.2, C* 0.0.

Mid, L* 50 to 65

Thirteen names, the most crowded band in the set, and the one where the blue bias is impossible to miss. Eight of the thirteen are tinted and seven of those eight are cool.

  • Steel gray, #71797e. L* 50.3, C* 4.2, hue 243.1.
  • Slate gray, #708090. L* 52.8, C* 10.8, hue 258.5. A CSS keyword.
  • Gray, #808080. L* 53.6, C* 0.0. The CSS keyword, and the only name in the set that is exactly half of every channel.
  • Battleship gray, #848482. L* 55.1, C* 1.1, hue 110.0.
  • Light slate gray, #778899. L* 55.9, C* 11.3, hue 258.6. Hex 77 88 99, which is why it stuck.
  • Taupe gray, #8b8589. L* 56.2, C* 3.3, hue 336.0.
  • Smoke, #848884. L* 56.3, C* 2.8, hue 144.3.
  • Roman silver, #838996. L* 57.0, C* 7.7, hue 274.1.
  • Philippine gray, #8c8c8c. L* 58.3, C* 0.0.
  • Pewter, #899499. L* 60.6, C* 4.9, hue 233.9.
  • Cool gray, #8c92ac. L* 60.9, C* 14.7, hue 283.5. The most tinted name in the entire set, which is at least honest about it.
  • Spanish gray, #989898. L* 62.8, C* 0.0.
  • Manatee, #979aaa. L* 63.8, C* 9.0, hue 284.1.

Light mid, L* 65 to 80

Ten names, and the pattern flips. This is the one band where warm grays get a look in, and it is also where the naming gets so crowded that several of these are not separable by eye. More on that below.

  • Cadet gray, #91a3b0. L* 66.0, C* 9.5, hue 248.4.
  • Quick silver, #a6a6a6. L* 68.1, C* 0.0.
  • Dark gray, #a9a9a9. L* 69.2, C* 0.0. A CSS keyword, and 15.7 lightness points lighter than the keyword called gray. That is not a typo, and the reason is worth its own section.
  • Silver chalice, #acacac. L* 70.4, C* 0.0.
  • Greige, #beb6a6. L* 74.3, C* 9.2, hue 89.6. A portmanteau of gray and beige, and the warmest name in the set.
  • Ash gray, #b2beb5. L* 75.8, C* 6.6, hue 151.9. Green. Actual wood ash is warm gray, so the name and the hex disagree.
  • French gray, #bdbdbd. L* 76.6, C* 0.0.
  • Gray (X11), #bebebe. L* 77.0, C* 0.0. The original Unix value for the word gray, before the web overruled it.
  • Silver, #c0c0c0. L* 77.7, C* 0.0. A CSS keyword.
  • Silver sand, #bfc1c2. L* 77.9, C* 0.9, hue 235.8.

Near white, above L* 80

Ten names. Chroma collapses here for a boring physical reason: to be this light in sRGB, all three channels have to be close to maximum, and channels close to maximum cannot differ from each other by much. The gamut simply runs out of room for a tint.

  • Chinese silver, #cccccc. L* 82.0, C* 0.0.
  • Light gray, #d3d3d3. L* 84.6, C* 0.0. A CSS keyword.
  • Timberwolf, #dbd7d2. L* 86.2, C* 3.0, hue 80.7.
  • Light silver, #d8d8d8. L* 86.3, C* 0.0.
  • Gainsboro, #dcdcdc. L* 87.8, C* 0.0. A CSS keyword, named after a district in Lincolnshire by way of the painter.
  • Platinum, #e5e4e2. L* 90.6, C* 1.1, hue 91.0.
  • Isabelline, #f4f0ec. L* 95.0, C* 2.5, hue 75.0.
  • Anti-flash white, #f2f3f4. L* 95.8, C* 0.6, hue 255.5.
  • White smoke, #f5f5f5. L* 96.5, C* 0.0. A CSS keyword.
  • White, #ffffff. L* 100.0, C* 0.0.

Why the gray vocabulary leans blue

Seventeen cool names against nine warm ones is a lopsided enough split that it wants an explanation. The chroma gap is the more telling half of it: when a gray name leans cool it carries a mean chroma of 7.13, and when it leans warm it carries 3.52. Cool grays are not just more common, they are more committed.

My reading is that the names are recording shadow, not pigment. Under daylight, the direct light is warm and the fill light in shadow comes from the sky, which is blue. So the gray surfaces people spent centuries naming were disproportionately being lit by blue light: slate roofs, gunmetal, pewter, steel, the sea under cloud. When those names were fixed as hex values by people picking from memory, the memory came with the sky attached.

The warm names support this by being the exceptions that prove it. Greige, timberwolf, isabelline and platinum are all either textile terms or precious-metal terms, and both of those categories describe objects you look at indoors, held close, under whatever light you brought with you. Take the sky away and the blue goes with it.

I want to be careful here, because this is an interpretation of a measurement rather than a second measurement. The numbers are solid: 17 against 9, 7.13 against 3.52, mean b* of negative 1.74. The story about skylight is the most economical explanation I can find for them, and it is consistent with what color constancy research says about how aggressively the visual system discounts the illuminant. It is not proof.

The practical consequence is real regardless of the cause. If you pick a gray by name rather than by number, you are probably picking a blue one. Four of the CSS gray keywords carry chroma above 10, and cool gray sits 11.3 CIEDE2000 units away from the nearest true neutral of the same lightness. That is not a subtle difference. Dark slate gray is 12.8 units off neutral, which is further than the gap between many pairs of colors people would call unambiguously different.

sRGB gives you 256 grays. You can see about 67 of them

The neutral axis in 8-bit sRGB has exactly 256 positions, from #000000 to #ffffff, where all three channels hold the same value. That sounds like a lot of gray. It is not, and it is also more than you need, because the 256 are not spaced the way your eye is.

I converted all 256 to CIELAB and ran CIEDE2000 between every adjacent pair. The result is unambiguous:

  • Every one of the 255 adjacent steps is below the just-noticeable difference of 1.0. Not most of them. All of them.
  • The mean step is 0.295. The largest step in the entire ramp is 0.398, at value 117.
  • The smallest step is 0.157, right at the black end between #000000 and #010101.
  • Walk the ramp greedily, keeping a gray only when it is at least 1.0 CIEDE2000 from the last one you kept, and you end up with 67 grays. Raise the bar to 2.3, the just noticeable difference where a difference is obvious rather than merely detectable, and you get 31.

So the honest headline is that 8-bit gray is finer than human vision by a factor of roughly four. The codes from #808080 to #838383 are, as isolated patches, the same color.

There is a catch, and it is the reason gradients still band visibly on cheap screens. The 1.0 threshold applies to two patches with a hard edge between them, which is the condition CIEDE2000 was fitted against. A smooth gradient is a much easier detection task, because the eye is built to find edges and a banding boundary in an otherwise smooth field is exactly that. Sensitivity there is several times better than the patch threshold. This is why 10-bit displays are worth something for gradients and worth nothing for flat swatches, and it is a good example of why a single JND number should be treated as a rule of thumb rather than a law.

The distribution is also more even than I expected. Splitting the ramp into quarters, the mean step is 0.275 in the darkest quarter, 0.366 in the second, 0.311 in the third and 0.225 in the lightest. The sRGB transfer function is doing its job. It was designed to make code values roughly perceptually uniform, and on this evidence it gets within about a 1.6x spread across the whole range, which is far better than the 50x spread I measured across the hue circle.

Gray or grey?

Both are correct. Gray is standard in American English, grey is standard in British English, and both descend from the same Old English grǣg with no difference in meaning whatsoever. Nothing distinguishes them except which side of the Atlantic set your spellcheck.

The one place it matters is code, and there the answer is unusually generous: CSS accepts both. gray and grey are the same keyword, as are darkgray and darkgrey, lightgray and lightgrey, dimgray and dimgrey, slategray and slategrey, and darkslategray and darkslategrey. The specification lists the pairs as exact synonyms. This is a rare piece of accommodation in a standard that is otherwise happy to make you memorise that the word for the color between red and blue is spelled fuchsia.

A small consistency note for anyone naming design tokens: pick one and never mix them. A palette with grey-100 next to gray-200 will cost somebody an afternoon eventually.

The reason dark gray is lighter than gray

In CSS, darkgray is #a9a9a9 and gray is #808080. Measured, dark gray is 15.7 lightness points brighter, a CIEDE2000 distance of 13.5. The color named dark is visibly the lighter of the two, and it has been that way for thirty years.

The cause is a collision between two color lists that were never meant to meet. The X11 window system shipped a set of color names in which gray meant #bebebe, with darkgray at #a9a9a9 and lightgray at #d3d3d3 arranged sensibly around it. Early HTML had its own much smaller list, inherited from VGA conventions, in which gray meant #808080, exactly half of full intensity in every channel. When the two lists were merged into the web platform, the HTML meaning of gray had too much existing content behind it to change, so #808080 kept the name and the X11 value was dropped. Its neighbours, darkgray and lightgray, had no competing HTML definitions, so they came across unchanged and now orbit a center that moved without them.

The same merge produced several other oddities that the history of the list records: seventeen colors got dark variants but only thirteen got light ones, and there is a mediumvioletred with no violetred to be medium relative to. The working group correspondence from 2002 is worth reading if you enjoy watching careful people conclude that a known defect has to be preserved forever.

The lesson generalises past this one bug. Color names are compressed history, not descriptions. If you need a gray that is actually darker than another gray, compare the numbers. Reading a hex code takes about ten seconds and it does not lie to you.

The eight pairs of named grays nobody can tell apart

Running all 1,275 pairs through CIEDE2000 turns up eight pairs below the 1.0 threshold and 21 below 2.3. These are distinct entries in shade references, sold as distinct choices, and they are the same color:

  • French gray #bdbdbd and gray (X11) #bebebe, at 0.26. This is a quarter of a JND. No observer separates these.
  • Gray (X11) #bebebe and silver #c0c0c0, at 0.52.
  • Anti-flash white #f2f3f4 and white smoke #f5f5f5, at 0.77.
  • French gray #bdbdbd and silver #c0c0c0, at 0.78.
  • Dark gray #a9a9a9 and silver chalice #acacac, at 0.87.
  • Quick silver #a6a6a6 and dark gray #a9a9a9, at 0.88.
  • Light silver #d8d8d8 and gainsboro #dcdcdc, at 0.92.
  • Silver #c0c0c0 and silver sand #bfc1c2, at 1.05, just over the line.

Every one of these sits between L* 68 and L* 88. The light-mid band is where gray naming has run out of road, and it is exactly the band a designer reaches into most often for borders, dividers and disabled states. If you have ever agonised over silver versus French gray for a one-pixel rule, the measurement says you were choosing between two names for one color.

Compare that to the family as a whole, where the mean pairwise distance is 26.4 and black to white spans the full 100. Gray is not short of range. It is short of range in the top third, and oversupplied with names there anyway.

What to do with this

  • Specify grays as numbers, not names. The names carry an average blue lean of b* negative 1.74 and at least one outright reversal in the CSS keyword set.
  • If you want a neutral gray, check the chroma. Equal R, G and B channels is the only reliable test. #737373 is neutral, charcoal is not.
  • If you want a warm gray, you will have to build it. The vocabulary offers you greige and timberwolf and not much else, and both are above L* 74. There is effectively no named warm gray in the dark half of the range.
  • Space a gray scale by CIEDE2000, not by hex arithmetic. Ten steps of equal hex spacing are not ten steps of equal perceived spacing, though for grays specifically the sRGB curve gets you closer than you might expect.
  • Do not put two grays within 1.0 of each other in the same interface and expect anyone to see them as different. Eight of the standard names already fail this against each other.

Test your own gray discrimination

Reading about a 1.0 threshold is not the same as finding out where yours actually is. A few ways to try it:

  • Spot the difference puts one off-shade tile in a grid of identical ones and shrinks the gap each round. It is the closest thing on the site to a direct JND measurement, and grays are the hardest case in it.
  • Hex asks you to read a color and name its code. Neutrals are deceptively hard because there is no hue to anchor the guess, only lightness.
  • Hue sort is the opposite exercise: all hue, no lightness cue. Playing the two back to back is a decent way to find out which axis you are better on.
  • The main color memory game shows a color, takes it away, and asks you to find it again. Recall degrades differently for neutrals than for saturated colors, which is the subject of the color memory article.

Related reading

  • Monochromatic colors covers building a scale from a single hue, which is the technique you need if you want a warm gray the vocabulary refuses to give you.
  • Warm and cool colors explains the temperature axis this whole article rests on, and where the intuition comes from.
  • What is CIEDE2000 explains the distance metric, including why a threshold of 1.0 is a convention rather than a constant.
  • Is black a color takes on the definitional end of the same problem from the other direction.
  • Color theory puts the wheel, the schemes and the primaries in one place.

Method

The 51 names are the gray, silver and charcoal keywords in the CSS named color set plus the names that recur across mainstream shade references with a settled hex value. Where a name has both an American and a British spelling it is counted once. Slate and slate gray resolve to the same hex and are counted once. All values were converted from sRGB to CIELAB under a D65 white point using the standard IEC 61966-2-1 transfer function, and all 1,275 pairs were compared with CIEDE2000 using the same implementation the site uses to score gameplay. Chroma is the CIELAB C* value and hue is the angle in the a*b* plane. The neutral ramp analysis covers all 256 values where R, G and B are equal. The greedy distinguishability walk starts at #000000 and keeps the next value that is at least the stated threshold from the last kept value, which gives a lower bound on the count rather than an optimal packing. Thresholds of 1.0 and 2.3 are the conventional detection and recognition figures for patch comparison and do not transfer to gradients, as noted above.