Accessibility guide
WCAG Contrast Between the Colors of a Color Palette
A color pair in a color palette passes WCAG 2.2 when its contrast ratio reaches 4.5:1 for normal text, 3:1 for large text and non-text UI parts, or 7:1 for Level AAA normal text. Checking a palette means calculating the contrast ratio of every color pair and comparing each pair that appears as text color on background color with the threshold for its use.
By Color Palette ExtractorPublished Updated 8 min read
What is a contrast ratio?
A contrast ratio is the WCAG measure of the luminance difference between two colors, calculated as (L1 + 0.05) / (L2 + 0.05). L1 is the relative luminance of the lighter color, and L2 is the relative luminance of the darker color. WCAG 2.2 is a W3C Recommendation, and its current version is dated 12 December 2024.
contrast ratio = (L1 + 0.05) / (L2 + 0.05)Contrast ratios range from 1:1 to 21:1. Two identical colors produce 1:1. Black (#000000) and white (#FFFFFF) produce 21:1, the maximum.
How is relative luminance calculated?
Relative luminance is calculated in three steps from the red, green and blue channels of an sRGB color. The result runs from 0 for black to 1 for white.
- Divide each 8-bit channel by 255 to get a value from 0 to 1 (R_sRGB = R8bit / 255).
- Linearize each channel with the sRGB transfer function shown below.
- Add the weighted channels: 0.2126 for red, 0.7152 for green and 0.0722 for blue.
R = R_sRGB / 12.92 if R_sRGB <= 0.04045, otherwise R = ((R_sRGB + 0.055) / 1.055) ^ 2.4L = 0.2126 * R + 0.7152 * G + 0.0722 * BThe green weight dominates the sum. Pure green (#00FF00) has a relative luminance of 0.7152, and pure blue (#0000FF) has a relative luminance of 0.0722. Pure blue therefore reaches 8.59:1 against white, and pure green reaches only 1.37:1 against white.
Which WCAG thresholds apply to palette colors?
WCAG 2.2 sets three contrast thresholds for palette colors: 4.5:1 for normal text at Level AA, 7:1 for normal text at Level AAA, and 3:1 for non-text UI parts and graphics at Level AA.
| Success criterion | Level | Applies to | Minimum contrast ratio |
|---|---|---|---|
| SC 1.4.3 Contrast (Minimum) | AA | Normal text and images of text | 4.5:1 |
| SC 1.4.3 Contrast (Minimum) | AA | Large-scale text | 3:1 |
| SC 1.4.6 Contrast (Enhanced) | AAA | Normal text and images of text | 7:1 |
| SC 1.4.6 Contrast (Enhanced) | AAA | Large-scale text | 4.5:1 |
| SC 1.4.11 Non-text Contrast | AA | UI component boundaries and states, graphics needed to understand content | 3:1 against adjacent colors |
The 4.5:1 threshold compensates for the contrast sensitivity loss typical of about 20/40 vision, according to the W3C Understanding document for SC 1.4.3. The 3:1 threshold is the minimum that ISO-9241-3 and ANSI-HFES-100-1988 recommend for standard text and vision. SC 1.4.11 entered the standard in WCAG 2.1.
What counts as large-scale text?
Large-scale text is text of at least 18 point, or at least 14 point bold. With 1 point equal to 1.333 CSS pixels, 18 point is about 24px and 14 point bold is about 18.5px, as stated in the W3C Understanding document. CJK fonts use an equivalent size.
Are contrast ratios rounded?
Contrast ratios are not rounded up to meet a threshold. W3C states that 4.499:1 does not meet the 4.5:1 threshold. Gray #767676 on white reaches 4.54:1 and passes AA for normal text. Gray #777777 on white reaches 4.48:1 and fails, although the two grays differ by one step per channel.
Which text has no contrast requirement?
Logotypes and incidental text have no contrast requirement under SC 1.4.3 and SC 1.4.6. A logotype is text that is part of a logo or brand name. Incidental text is text in an inactive UI component, pure decoration, invisible text, or text inside a picture with significant other visual content. The exception covers the logo itself, not brand colors reused for body text, headings or buttons. The guide to finding a logo's exact color codes shows how to read them.
How do you check every color pair in a palette?
Checking a color palette means listing every color pair, calculating the contrast ratio of each pair, and comparing that ratio with the threshold for the pair's intended use. A palette of n colors contains n(n - 1) / 2 color pairs. A palette of 6 colors has 15 pairs, and a palette of 10 colors has 45 pairs.
number of color pairs = n * (n - 1) / 2Each pair needs only one calculation, because the contrast ratio is symmetric. The formula always places the lighter color in the numerator, so swapping the text color and background color gives the same ratio.
Extract the palette
Pull the colors from an image with the Color Palette Extractor, or read them from a live site with the Website Color Extractor.
Calculate relative luminance
Convert each color to relative luminance with the WCAG 2.2 formula.
Calculate every pair
Apply (L1 + 0.05) / (L2 + 0.05) to each of the n(n - 1) / 2 color pairs.
Assign a role to each pair
Mark each pair as normal text, large-scale text, a UI component or graphic, or background only. The role sets the threshold.
Compare against the threshold
Compare each ratio with 4.5:1, 3:1 or 7:1 without rounding. Flag every text pair that falls below its threshold.
| Text color | Background color | Contrast ratio | Result |
|---|---|---|---|
#000000 | #FFFFFF | 21:1 | Passes AAA |
#0000FF | #FFFFFF | 8.59:1 | Passes AAA |
#767676 | #FFFFFF | 4.54:1 | Passes AA |
#FF0000 | #FFFFFF | 3.998:1 | Passes AA for large-scale text only |
#0000FF | #000000 | 2.44:1 | Fails all text thresholds |
#00FF00 | #FFFFFF | 1.37:1 | Fails all text thresholds |
The Color Palette Extractor shows each extracted color's WCAG 2 contrast ratio against white and against black, with AA and AAA badges. Its contrast table tests every color pair in the extracted palette and marks each pair as AA, AAA or AA Large. All processing happens in the browser. How color extraction works explains how the palette is chosen.
How common is low contrast on the web?
Low contrast text is the most commonly detected accessibility issue on the web. The WebAIM Million 2026 report found text below the WCAG 2 AA threshold on 83.9% of the top 1,000,000 home pages, up from 79.1% in 2025. WebAIM drew the home pages from the Tranco ranking and collected the data in February 2026. Each home page had 34 distinct instances of low contrast text on average, up 15% from 2025.
| Year | Home pages with low contrast text |
|---|---|
| 2019 | 85.3% |
| 2020 | 86.3% |
| 2021 | 86.4% |
| 2022 | 83.9% |
| 2023 | 83.6% |
| 2024 | 81% |
| 2025 | 79.1% |
| 2026 | 83.9% |
The 2026 figure reverses a four-year decline from 86.4% in 2021 to 79.1% in 2025. Low contrast text ranks first among the six most common failure types, which together cover 96% of all detected errors and have stayed the same for 7 years.
How do you fix a pair that fails?
A failing color pair is fixed by changing the lightness of one color until the contrast ratio reaches the threshold, while the hue stays the same. Darkening the text color or lightening the background color raises the ratio.
Change lightness in OKLCH
OKLCH separates lightness (L), chroma (C) and hue (H), so a lightness change leaves the hue angle untouched. HSL lightness does not track perceived lightness: sRGB blue and sRGB yellow both have an HSL lightness of 50%, while their OKLCH lightness is 0.452 and 0.968 (CSS Color 4). A constant-hue OKLCH slice around sRGB blue keeps the same visible hue, and the equivalent CIE LCH slice shows noticeable purpling. Recalculate the contrast ratio after each change, because WCAG uses relative luminance, not OKLCH lightness.
Pick a step from a tint and shade scale
A tint and shade scale offers ready lightness steps of one hue, from 50 (lightest) to 950 (darkest). For text on a light background color, move the text color toward the 950 end. For text on a dark background color, move the text color toward the 50 end. The Color Palette Extractor builds a 50 to 950 scale in OKLCH for every extracted color, so the replacement step keeps the original hue.
Test text on background, not background on background
The text thresholds apply to a text color against the background color behind it. Two background colors placed side by side carry no text contrast requirement. They need 3:1 under SC 1.4.11 only when their boundary identifies a UI component, a component state, or a part of a graphic needed to understand the content.
- Use a brand color that reaches 3:1 but not 4.5:1 for large-scale text, icons or input borders only.
- Use a brand color that fails with every palette color as a background color, and set white or black text on it, whichever gives the higher ratio.
- Recheck every pair that shares the changed color, because one change affects n - 1 pairs.
Does WCAG 3 change the contrast rules?
WCAG 3 does not change the contrast rules today. WCAG 3.0 is a W3C Working Draft dated 10 September 2026, and W3C states that the draft is inappropriate to cite as anything other than a work in progress.
- WCAG 3.0 status
- W3C Working Draft, 10 September 2026
- Text contrast requirement
- "Text contrast sufficient (minimum)", status Developing, measure "to be determined"
- Contrast algorithm
- Not chosen; the editor's note states it is yet to be determined
- APCA (Advanced Perceptual Contrast Algorithm)
- Absent from the WCAG 3.0 Working Draft; not a normative requirement
- Normative thresholds
- WCAG 2.2: 4.5:1, 3:1 and 7:1 remain the W3C requirements
Frequently asked questions about palette contrast
Does disabled button text need a 4.5:1 contrast ratio?
No. Text in an inactive UI component counts as incidental text under SC 1.4.3, and incidental text has no contrast requirement.
What contrast ratio does an input border or focus indicator need?
An input border or focus indicator that identifies a component or its state needs at least 3:1 against adjacent colors. SC 1.4.11 applies this threshold to visual information needed to identify UI components and their states.
Does anti-aliasing change the contrast check?
No. WCAG allows text contrast to be evaluated with anti-aliasing turned off, so the check uses the specified text color, not the blended edge pixels.
What background color does WCAG assume when none is specified?
WCAG assumes a white background when no background color is specified. Specifying a text color without a background color, or a background color without a text color, is a failure.
Can a brand color that fails 4.5:1 stay in the palette?
Yes. A brand color below 4.5:1 stays usable as a background color with a passing text color, as large-scale text or a UI boundary if it reaches 3:1, or inside the logo, which is exempt.