What the 500 in Blue-500 Means
How colour palettes number their shades, and why blue-500 means something different in each one
Most design systems ship colour as a set of palettes. Each hue is a ramp of shades running from light to dark, and each shade gets a number. In Tailwind, blue runs from blue-50 to blue-950, and red, green, yellow and grey use the same numbers. Designers pick shades by number in Figma, engineers write them into class names and tokens, and reviews refer to them the same way.
Because every hue shares the same numbers, it is easy to assume the numbers line up across hues. Take a primary button with white text on bg-blue-600. In Tailwind v3 that pairing has a contrast ratio of 5.17:1. A success button built the same way on bg-green-600 comes out at 3.30:1.
Contrast ratio is the measure the Web Content Accessibility Guidelines (WCAG) use for text legibility. It runs from 1:1, where text and background are identical, to 21:1, black on white. WCAG 2's AA level asks for at least 4.5:1 for body text and 3:1 for large text and interface elements. The blue button passes AA and the green one fails, though both use shade 600.
Two buttons with white text, one on Tailwind's blue-600 and one on green-600. The blue one measures 5.17 to 1 and passes AA. The green one measures 3.30 to 1 and fails AA for body-size text.
Stefan Bauer wrote about these numbered scales in a 2021 post covering Material, Bootstrap and Tailwind, and compared them to the 100 to 900 scale CSS uses for font weight. Looking across more systems, the numbers are used in at least four different ways. In some palettes a number is a position in the ramp. In others the gap between two numbers guarantees a contrast ratio, the number is a measured lightness, or the number names what the shade is for. Each palette decides what its numbers mean. Many teams use palettes where the numbers only record position.
Four blue palettes, each with its main button colour marked. In Material 2014 it is 500, a position in the ramp. In Carbon it is blue 60, a grade whose distance from another grade guarantees contrast. In Material 3 it is tone 40, a measured lightness. In Radix it is step 9, a named role.
Numbered by position
Material Design introduced its palette in 2014. Each hue had ten shades numbered 50 to 900, plus four brighter accent shades named A100, A200, A400 and A700. Google's guidance suggested using the 500 shades as an app's primary colours and the others as accents.
Material Design's 2014 indigo and amber palettes. Each has ten shades numbered 50 to 900 and four accents, A100, A200, A400 and A700. The 500 shade is marked as the primary colour.
@mui/material/colors.Tailwind adopted the scale for version 1.0. In March 2019 Adam Wathan wrote that the palette was going from seven shades per colour to nine, “using a numeric scale borrowed from Material Design.” Tailwind added a 50 shade in version 2.0 in November 2020 and a 950 shade in version 3.3 in March 2023.
Material and Tailwind use the number for a shade's position within its own hue. The same number can have a different lightness in each hue.
One reason is how colour models measure lightness. In HSL, a colour model that has been part of the CSS standard since 2011, the lightness value is the average of the highest and lowest of the red, green and blue channels. Pure yellow (255, 255, 0) and pure blue (0, 0, 255) both average to 50%. People see yellow as much lighter than blue, because the eye is more sensitive to red and green light. On the CIELAB scale, which is designed to match perceived lightness from 0 for black to 100 for white, that yellow measures about 98 and that blue about 30. A ramp built by stepping HSL lightness carries that difference into every shade.
Tailwind v3 shows the effect. Measured in OKLCH, a colour space whose lightness value (0 to 1) is also designed to match perception, the 500 shades of Tailwind's seventeen colour families range from 0.585 for indigo to 0.795 for yellow. Its five greys sit between 0.551 and 0.556.
Every Tailwind v3 colour family at shade 500, sorted by lightness, each over a grey of the same perceived lightness. The colour families run from indigo at 0.585 to yellow at 0.795.
Contrast depends on lightness, so the same pair of numbers gives a different ratio in each hue. Text in shade 200 on a background in shade 700 passes AA in violet at 5.12:1 and fails in yellow at 4.23:1. Across Tailwind's seventeen colour families, 200 on 700 fails AA in twelve. The reverse pairing, 500 on 900, passes in one colour family, yellow.
Choose a text step and a background step, and nine Tailwind v3 colour families are shown at that pairing with their WCAG 2 contrast ratios. At 200 on 700, 6 of the nine fall short of AA.
AA 4.5:1 or more, body textLarge 3:1 to 4.5:1, large text onlyFail under 3:1
Material's 2014 palette works the same way. White text on its 500 shades ranges from 7.33:1 on deep purple to 1.63:1 on amber and 1.22:1 on yellow.
Fourteen Material Design 2014 colours at 500 with white text, from deep purple at 7.33 to 1 down to yellow at 1.22 to 1.
@mui/material/colors.In these palettes a rule that names shade numbers, such as text in 200 on a 700 background, can't be written once for the whole palette. It passes in some hues and fails in others, so each pairing has to be checked on its own. The two buttons at the top are the same problem. White text on 600 passes in blue and fails in green.
Numbered for contrast
IBM's Carbon design system numbers each colour's shades from 10 to 100 and ties the numbers to contrast. Its colour guidance states: “If the difference between two values is 50 or greater, the colors are accessible.” In Carbon's blue, grade 20 text on a grade 60 background, 40 apart, is 3.81:1. On grade 70, 50 apart, it is 5.94:1. Every pair of Carbon blues 50 or more apart measures at least 4.55:1.
Carbon's blue grade 20 as text on every other blue grade. Grades 50 or more away, 70 and above, pass AA. Grade 60, 40 away, measures 3.81 to 1.
blue 20 as text on each blue grade, with the gap between the grades. Carbon's rule is a gap of 50 or more, marked with a line under the sample. Values from @carbon/colors.The US Web Design System (USWDS) uses the same idea. A proposal posted on 1 December 2017, which credits a palette developed at IBM, set out a scale from 0 for white to 100 for black. In the current system each grade covers a fixed range of relative luminance, so grade 50 has the same luminance in every colour family. USWDS calls the difference between two grades the magic number. A difference of 40 or more meets AA for large text, 50 or more meets AA for body text, and 70 or more meets AAA.
Five USWDS colour families, red, yellow, green, blue and violet, laid out by grade from 5 to 90. Each column has the same luminance. Below, grade 20 text on grade 70, a magic number of 50, passes AA in yellow, blue and violet.
Stripe published a similar rule. In October 2019 Daryl Koopersmith and Wilson Miner described rebuilding Stripe's palette in CIELAB, after finding that none of its default colours for small text, apart from black, met the WCAG contrast threshold. In the new palette any two colours at least five levels apart meet the threshold for small text, and any two at least four levels apart meet it for icons and large text.
A diagram of Stripe's rule. Two colours four levels apart meet the contrast threshold for icons and large text. Two colours five levels apart meet it for small text.
In these palettes the rule can be written once. Grade 20 text on a grade 70 background passes AA in every Carbon family, and across Carbon's twelve full colour families every pair of grades 50 or more apart measures at least 4.52:1. USWDS holds across all 25 of its standard colour families, at 4.56:1 or more. The cost of that consistency shows up in yellow, covered in the next section.
Numbered by lightness, and by role
Google replaced its own scale with Material 3 in 2021. James O'Leary, a colour scientist at Google, created a colour space called HCT for the Material You release. It takes hue and chroma from the CAM16 colour-appearance model and takes tone from CIELAB's lightness value. Material 3 palettes number their shades by tone, from 0 to 100. Tone 40 is a colour with a CIELAB lightness of 40, whatever its hue. The source code of Material's colour library states the contrast rule. A difference of 40 in tone guarantees a ratio of at least 3:1, and a difference of 50 guarantees at least 4.5:1.
Material 3 tonal palettes for blue, yellow and red, tones 0 to 100. Tones 40 and 90 are marked. In each, tone 40 on tone 90, a difference of 50, measures above 4.5 to 1.
material-color-utilities. Tones 40 and 90 are 50 apart, so the library guarantees at least 4.5:1 between them.Radix Colors numbers its twelve steps by what each one is for. Steps 1 and 2 are app backgrounds, 3 to 5 are component backgrounds, 6 to 8 are borders, 9 and 10 are solid fills, and 11 and 12 are text. Radix states its text contrast in APCA terms, a newer contrast method covered below. Steps 11 and 12 are guaranteed Lc 60 and Lc 90 on a step 2 background from the same scale.
Radix's twelve blue steps grouped by role: 1 and 2 app backgrounds, 3 to 5 component backgrounds, 6 to 8 borders, 9 and 10 solid fills, 11 and 12 text. Steps 11 and 12 are shown as text on step 2.
@radix-ui/colors.USWDS and Material 3 define each grade by lightness, so every hue has to fit the same lightness at each grade. Yellow shows what that means in practice. Tailwind's yellow-500 is #eab308, a bright yellow. USWDS's yellow-50 is #8a7237, and Material 3's yellow at tone 40 is #6d5e0f. Both are dark olive, because grade 50 and tone 40 are defined by lightness, and a bright yellow is too light to sit there.
Three middle yellows. Tailwind's yellow-500 is a bright yellow. USWDS's yellow-50 and Material 3's yellow at tone 40 are dark olive, because their grades are defined by lightness.
In both systems the same grade gives close to the same contrast in every hue. Against white, Material 3's tone 40 measures between 6.43:1 and 6.50:1 across the eight hues tested here, and USWDS's grade 50 between 4.58:1 and 4.63:1 across its families.
Radix makes the decision at a different level. A team using Radix picks a role rather than a shade number and a pairing to check. Body text is step 12, a button fill is step 9, and the contrast between those roles is set by the palette.
The contrast formula
Apart from Radix's, all of these guarantees are calculated with WCAG 2's formula. WCAG 2.0 became a W3C Recommendation on 11 December 2008 and defines contrast as a ratio of the relative luminance of two colours.
contrast = (L1 + 0.05) / (L2 + 0.05)
L1 relative luminance of the lighter colour
L2 relative luminance of the darker colourThe thresholds come from earlier standards. ISO 9241-3 and ANSI/HFES 100-1988 set 3:1 as the minimum for normal vision, and WCAG raised it to 4.5:1 to cover readers with 20/40 vision. USWDS defines its grades using the same relative luminance, and Carbon's and Material 3's rules are stated as WCAG ratios.
The formula gives the same ratio whichever colour is the text and whichever is the background. USWDS's documentation says its grade 50 colours meet AA against both pure white and pure black. Its grade 50 grey, #757575, measures 4.61:1 on white and 4.56:1 on black.
The Accessible Perceptual Contrast Algorithm (APCA), developed by Andrew Somers as a candidate method for the next version of WCAG, scores the two pairings differently. It reports lightness contrast as an Lc value, and gives that grey Lc 72.0 as text on white and −29.6 as text on black. The sign shows which way round the colours are. By APCA's measure, the grey on black has less than half the contrast of the grey on white.
USWDS's grade-50 grey, #757575, as body text on white and on black. WCAG 2 scores both at about 4.6 to 1. APCA scores them Lc 72.0 on white and minus 29.6 on black.
gray-50, #757575, as body text. WCAG 2 ratios computed from the hex. APCA values from the apca-w3 package, version 0.1.9. APCA is a candidate method and not part of any published WCAG standard.WCAG 3 has not settled on a replacement formula. APCA was included in the WCAG 3 working draft as exploratory content and removed in the July 2023 draft, after it did not get enough support in the working group. Adrian Roselli's review of the draft as of April 2026 notes that it still says the contrast algorithm “is yet to be determined,” and that WCAG 3 is unlikely to be finished before 2030.
If WCAG 3 adopts a different formula, a USWDS magic number of 50 will still describe the same luminance difference, but whether that difference meets the new standard would need to be checked again. The same applies to Carbon's difference of 50, Stripe's five levels and Material 3's tone difference of 50.
Changing a palette people already use
Tailwind released version 4.0 on 22 January 2025 and moved its default palette from rgb to oklch, using the wider colour range of modern displays to make the colours more saturated. The announcement said the team had tried to keep the balance between the colours the same as in v3, so that the change “shouldn't feel like a breaking change” for existing projects.
Comparing the two versions shows how closely that was done. Tailwind v4 has 242 shades across 22 families. In 220 of them the OKLCH lightness matches v3 to three decimal places. The other 22 are the 400 shade in every family, each made darker by 0.007 to 0.009. Almost all of the change is in chroma, meaning saturation.
/* blue-500 in v3 and v4 */
v3: #3b82f6 /* oklch(0.623 0.188 259.8) */
v4: oklch(0.623 0.214 259.815) /* same lightness, more chroma */Because lightness stayed the same, contrast changed very little. On an sRGB display, every v4 shade is within about 4% of its v3 contrast ratio against white and against black, and only one of those 484 pairings moves across the 4.5:1 line. White on blue-600 goes from 5.17:1 to 5.26:1. Keeping the lightness also means that yellow-500 is still at 0.795 and indigo-500 at 0.585, so the numbers still describe position and not lightness.
Tailwind's blue, yellow and violet ramps in v3 and in v4. The v4 colours are more saturated, and every step keeps the lightness it had in v3 except the 400, which is slightly darker.
Tailwind's numbers also spread beyond Tailwind. In August 2025 Adam Wathan joked about formally apologising for making every button in Tailwind UI bg-indigo-500 five years earlier, “leading to every AI generated UI on earth also being indigo.” The Default Is Not a Design Decision looks at how defaults like this get repeated by AI design tools.
Design specs, guidelines and code reviews often give colour as shade numbers, such as text in 200 on a 700 background. In Tailwind and in Material's original palette, an instruction like that depends on the hue. It passes in violet and fails in yellow, and white text on 600 passes in blue and fails in green. In Carbon, USWDS and Material 3 the same instruction holds in every hue, because those systems decided what the number measures and made every colour fit it, olive yellow included. blue-500 means whatever its palette decided it means, and in many of the palettes teams use, that is only where the shade sits in the ramp.