Chart Color Accessibility Checklist 2026
An accessible chart keeps its meaning when hue is removed. Under WCAG 2.2, the lines, bars and slices a reader needs must reach 3:1 contrast against adjacent colors unless text labels carry the same information, chart text needs 4.5:1, and color can never be the only cue. Everything else on this page is how to get there.
That last rule matters more for charts than for any other part of an interface. Two series that differ only in hue can be identical to a reader with a red-green color vision deficiency, to anyone viewing a grayscale printout, and to a stakeholder squinting at a compressed screenshot in a chat thread. The checks below are written for designers specifying dashboards and the developers building them, and they include a palette with every contrast ratio calculated.
Which accessibility rules apply to a chart
Charts are touched by more success criteria than people expect. This table maps chart parts to the WCAG 2.2 criterion that governs them.
| Chart part | Criterion | What it requires |
|---|---|---|
| Series told apart by color | 1.4.1 Use of Color (A) | A second visual cue: label, pattern, shape, line style or position |
| Axis labels, data labels, legend text, tooltip text | 1.4.3 Contrast (Minimum) (AA) | 4.5:1, or 3:1 for large text |
| Lines, bars, slices, markers a reader needs | 1.4.11 Non-text Contrast (AA) | 3:1 against adjacent colors, unless text conveys the same information |
| Focus ring on interactive points | 1.4.11 and 2.4.7 Focus Visible (AA) | Visible focus with 3:1 against its surroundings |
| Hover tooltips | 1.4.13 Content on Hover or Focus (AA) | Dismissible, hoverable and persistent |
| Interactive filters, zoom, drill-down | 2.1.1 Keyboard (A) | Everything works from a keyboard |
| The chart as a whole | Text alternatives | A short name plus a long description or data table |
Our WCAG 2.2 AA guide explains the contrast formula and the general thresholds. The rest of this page applies them to data graphics, where the questions are different: which colors sit next to each other, which marks are required, and what a label replaces.
What W3C actually says about charts
The W3C Understanding document for 1.4.11 Non-text Contrast is unusually specific about graphs. Its points, paraphrased with short quotes:
- Required parts only. Graphical objects are "the important parts of a more complex diagram such as each line in a graph." The document states that "not every graphical object needs to contrast with its surroundings."
- Lines against the background. In a line graph, the lines need 3:1 against the background. Lines that do not overlap much do not need to contrast with each other or with the gridlines.
- Pie slices against each other. Adjacent slices must be distinguishable, and the failing example is one where slice-to-slice contrast is below 3:1. The passing fix in W3C's example adds a darker outline to the problem slice.
- Labels can replace contrast. When text on the chart gives the labels and values, the marks themselves are not required for understanding, so their contrast is not required. The text still has to meet 1.4.3.
- Gradients. Test the least-contrasting area, or check whether the object is still understandable with that area removed. Heat maps that represent a measurement can fall under the essential exception.
- Thin lines. Anti-aliasing makes thin lines look fainter, so the document advises avoiding particularly thin lines and shapes or using stronger color combinations.
- Interactive charts. The unfocused default must already have sufficient contrast or text; focus can reveal more, but cannot be the only way to make a series readable.
The 1.4.1 Understanding page adds a sales-chart example that fails ("Mary's sales are in red, Tom's are in blue") and lists technique G111, using color and pattern together, as one fix.
Start from the chart's job
Choose the color scheme after you know what the chart has to say.
| Chart purpose | Scale type | Color rule | Second cue |
|---|---|---|---|
| Compare unrelated categories | Categorical | Distinct hues with different lightness | Direct labels or markers |
| Show intensity or amount | Sequential | One hue, light to dark, ordered by lightness | Numbered legend, value labels on hover and focus |
| Show above and below a midpoint | Diverging | Two hues meeting at a neutral middle | Labeled midpoint, plus and minus signs |
| Show status | Semantic | Reserved meaning colors | Icon and word, every time |
| Highlight one series against context | Accent | One strong color, everything else gray | Thicker stroke and a direct label |
Rainbow scales fail most of these jobs. Their lightness rises and falls across the range, so the brightest band reads as a peak in the data whether or not one exists, and readers without full color vision lose the order entirely. For broader palette construction, the accessible color systems guide covers building scales by lightness, and the color theory guide explains why hue and lightness behave differently.
A colorblind-safe palette, with every ratio calculated
Masataka Okabe and Kei Ito published a color universal design set intended to stay distinguishable for people with common color vision deficiencies. Their Color Universal Design page notes that red-green deficiency affects about 8 percent of Caucasian males, 5 percent of Asian males and 4 percent of African males, and advises using vermilion rather than pure red and avoiding red-green pairs.
The hex values below are the ones R ships in its grDevices package as the "Okabe-Ito" palette, in R's order. Our editorial team calculated each contrast ratio with the WCAG relative luminance formula against white (#FFFFFF) and a near-black dark-mode surface (#121212).
| Name in R | Hex | On white | On #121212 | Line on white without labels |
|---|---|---|---|---|
| black | #000000 | 21.00:1 | 1.12:1 | Pass (axes and text) |
| orange | #E69F00 | 2.25:1 | 8.32:1 | Fail |
| skyblue | #56B4E9 | 2.31:1 | 8.12:1 | Fail |
| bluishgreen | #009E73 | 3.42:1 | 5.48:1 | Pass |
| yellow | #F0E442 | 1.32:1 | 14.17:1 | Fail |
| blue | #0072B2 | 5.19:1 | 3.61:1 | Pass |
| vermillion | #D55E00 | 3.87:1 | 4.84:1 | Pass |
| reddishpurple | #CC79A7 | 3.06:1 | 6.12:1 | Pass (narrowly) |
| gray | #999999 | 2.85:1 | 6.58:1 | Fail |
What the numbers say
- On white, only four colored series clear 3:1: blue, vermillion, bluish green and reddish purple. Orange, sky blue, yellow and gray need direct value labels, a dark outline, or a thick stroke plus labels to be used as required marks.
- On a dark surface, the picture flips. Every color except black clears 3:1 on #121212, and blue is the weakest at 3.61:1. A palette checked only on white is not checked.
- Hue pairs can have nearly identical lightness. Orange and sky blue measure 1.02:1 against each other; bluish green and reddish purple 1.12:1; bluish green and vermillion 1.13:1. In grayscale those pairs become the same gray. That is fine for separated lines, which W3C says need not contrast with each other, but adjacent slices or stacked segments need an outline or a label.
- Among the eight non-black colors, only one pair reaches 3:1 against each other: yellow and blue, at 3.92:1. Black clears 3:1 against every colored entry, which is why a black outline works as a separator.
Separators: white gaps are not enough on light fills
A common fix for stacked bars is a thin white gap between segments. Measured against white, that gap gives blue 5.19:1, vermillion 3.87:1, bluish green 3.42:1 and reddish purple 3.06:1, but orange only 2.25:1, sky blue 2.31:1 and yellow 1.32:1. A black outline does better on the light colors: 9.32:1 against orange, for example. Outline with a dark stroke when the light colors appear in adjacent fills, or label the segments directly.
Rules for using the set
- Assign colors in a fixed order and keep that order across every chart in a product, so a series keeps its color from page to page.
- Reserve yellow for highlights and backgrounds of callouts on white; it is too light for lines or small markers.
- On white, put the four 3:1 colors on the series that readers must trace without labels.
- Cap a single chart at about six colored series. Past that, readers spend more time matching legend swatches than reading data; group the remainder into "Other" or split into small multiples. This is an editorial rule of thumb, not a WCAG requirement.
Check your own brand colors the same way with our contrast checker, testing each series against the plot background and against its neighbors.
Worked example: a four-series line chart
Inputs. A revenue dashboard on a white background plots four regions over twelve months. Lines are 2px. The design team's first draft uses orange, sky blue, bluish green and yellow.
Problems found.
- Orange (2.25:1), sky blue (2.31:1) and yellow (1.32:1) are below 3:1 against white, and the chart has no value labels, so three of four lines fail 1.4.11.
- Orange and sky blue are 1.02:1 apart. In a grayscale print they are indistinguishable.
- The legend uses colored squares only, so 1.4.1 fails as well: color is the only link between a line and its region name.
Revision.
| Region | Color | Ratio on white | Line style | Marker |
|---|---|---|---|---|
| North | blue #0072B2 | 5.19:1 | Solid | Circle |
| South | vermillion #D55E00 | 3.87:1 | Dashed | Square |
| East | bluish green #009E73 | 3.42:1 | Dotted | Triangle |
| West | reddish purple #CC79A7 | 3.06:1 | Dash-dot | Diamond |
Each line also gets a direct label at its right end, in #1F2937 text (14.68:1 on white). The legend is removed because the labels replace it. Line weight goes to 2.5px because reddish purple sits close to the 3:1 line and thin anti-aliased strokes read lighter than their nominal color.
Result. Every required line now clears 3:1, every series has a non-color cue twice over (style and marker), and labels remove the need to match swatches. The chart passes 1.4.1 and 1.4.11 on white. Before shipping the dark theme, re-run the same table on the dark surface, where blue drops to 3.61:1 and black text would vanish.
Redundant cues that survive any rendering
Hue is the least reliable channel in a chart that will be printed, screenshotted, projected or viewed by a reader with a color vision deficiency. These cues survive all of those.
| Cue | Best for | Watch out for |
|---|---|---|
| Direct labels at line ends | Up to about five series | Collisions when lines converge; nudge labels vertically |
| Line style (solid, dashed, dotted, dash-dot) | Line charts, forecast vs actual | Dots vanish at 1px or in heavy JPEG compression |
| Marker shape | Scatter plots, sparse line charts | Clutter on dense series; mark every Nth point |
| Pattern fill (hatching, dots) | Bars and areas in print | Busy at small sizes; keep patterns coarse |
| Position and sorting | Bar charts | Requires a stable sort the reader can predict |
| Stroke weight | Highlighting one series | Only works for one emphasis level |
A convention that keeps reports consistent: solid for actual or selected, dashed for forecast or projected, dotted for target or benchmark, dash-dot for the previous period. Draw the same style in the legend entry, because a legend of colored squares beside a chart of dashed lines gives readers nothing to match.
Labels, legends and tooltips
Direct labels first. A value or series name next to the mark removes the matching step entirely, and W3C's guidance means labeled marks no longer need their own 3:1 contrast. Keep label text at 4.5:1 against whatever sits behind it, including colored bars when labels sit inside them. White text on orange is only 2.25:1; use dark text on the lighter palette colors.
Legends when labels do not fit. Put the legend next to the plot, in the same order as the series appear, at the same size as axis labels, with the real line style or marker drawn in each entry.
Tooltips carry precision but cannot carry meaning alone. Under 1.4.13, extra content that appears on hover or focus must be dismissible, hoverable and persistent: readers can close it (Escape is the usual way), move the pointer onto it without it vanishing, and keep it on screen until they dismiss it or it stops being relevant. On touch screens there is no hover, so anything only available in a tooltip is missing on phones. Provide a tap target, a data table, or values on the chart.
Interactive points need focus. If readers can tab through data points, give each a visible focus ring with 3:1 contrast against the plot, and make sure keyboard focus reveals the same tooltip as hover.
Text alternatives for charts
A chart image needs two text parts, according to W3C's complex images tutorial: a short description that identifies the chart, and a long description with the essential data, trends and relationships. The tutorial lists several ways to connect them, such as a <figure> that wraps the chart and its description in a <figcaption>, or a link to a data table. It also recommends making the long description visible to everyone rather than hidden. The exception is a chart that only repeats figures already stated in the text next to it, which the HTML Standard says takes an empty alt; our decorative vs informative alt text decision table shows that case alongside the other image types.
For inline SVG charts, MDN's guidance on the img role applies: put role="img" and an aria-label (or aria-labelledby pointing at a visible title) on the outer <svg>, so screen readers treat it as one image. MDN also warns that browsers make every child of an img role presentational. Any axis text or labels inside the SVG then become invisible to assistive technology, which is exactly why the long description or a real HTML data table is needed.
<figure>
<svg role="img" aria-labelledby="rev-title" viewBox="0 0 640 360">
<title id="rev-title">Revenue by region, 2026, in millions of dollars</title>
<!-- lines, markers, labels -->
</svg>
<figcaption>
North led every quarter and finished at $4.2M. West grew fastest,
from $1.1M in January to $2.6M in December.
<a href="#rev-table">View the data table</a>
</figcaption>
</figure>
The figures in that caption are placeholders for illustration. Write the description from your own data, stating the conclusion the chart is meant to support, not a list of every value. The SVG cleanup guide covers keeping <title> elements and IDs intact when exporting and minifying chart SVGs, since aggressive cleanup settings can strip them.
Dark mode and forced colors
Dark mode needs its own pass. The palette table above shows ratios rising for light hues and falling for blue on a dark surface. Gridlines that were subtle gray on white may turn into bright stripes. Re-check every series against the dark plot color, re-check label text inside bars, and lower the saturation of colors that glare. The dark mode design guide covers choosing the surface tones themselves.
Forced colors mode can erase your palette. MDN explains that when forced-colors: active matches, as in Windows contrast themes, the browser replaces author colors on properties including SVG fill and stroke, and forces box-shadow to none. A line chart that distinguishes series only by stroke color can render every line in the same system color. Charts built with line styles, markers and direct labels keep working. If you must preserve series colors, MDN documents forced-color-adjust: none for the chart element; use it sparingly and only after checking that the preserved colors still contrast with the user's chosen background, since you no longer control what that background is.
@media (forced-colors: active) {
.chart-series { stroke: CanvasText; }
.chart-series--forecast { stroke-dasharray: 6 4; }
.chart-gridline { stroke: GrayText; }
}
Hex codes for ready-made colour-blind-safe palettes, with simulated colour-difference scores for each and the best subsets of Okabe-Ito for three to seven series, are in color-blind friendly palettes: hex codes, tested.
Testing routine before a chart ships
- Contrast table. List every series color, the plot background and each pair of adjacent fills. Calculate ratios and mark which marks are required.
- Vision emulation. In Chrome DevTools, open the Rendering tab and step through the vision deficiency options Chrome documents: blurred vision, reduced contrast, protanopia, deuteranopia, tritanopia and achromatopsia. Achromatopsia is the quickest grayscale test.
- Forced colors. In the same tab, emulate
forced-colors: activeand confirm series stay distinguishable. - Keyboard and screen reader. Tab through interactive points; check that the chart's name and description are announced.
- Export. Save the chart as PNG, view it at phone width, and paste it into a slide with a different background. Thin lines and pale gridlines fail here first.
- Print. Print to grayscale. If two series merge, add a style or a label. Color conversion for print has its own pitfalls, covered in the CMYK vs RGB print color guide.
Walkthrough: fixing a fragile dashboard
Starting state. A sales dashboard shows five product lines in saturated rainbow colors, a legend in 10px light gray text, and red and green status badges with no words.
Fixes, in order.
- Gray out four of the five lines at a weight that still clears 3:1 (#6B7280 measures 4.83:1 on white) and give the decision line, total revenue, the strongest color, a thicker stroke and a direct label.
- Turn status badges into icon plus word: a check and "On track," a triangle and "At risk." The color stays, but it is no longer the only signal, which satisfies 1.4.1.
- Raise legend text to axis-label size and a 4.5:1 color, and move the legend beside the plot.
- Replace the second colored "target" series with a dotted reference line and a direct label.
- Re-run the dark-mode, forced-colors and grayscale checks.
The revised dashboard uses fewer colors and states more. Strong color appears only where a decision is made.
Handoff specification for a chart system
Document these so the next designer or developer does not rebuild the rules from scratch:
| Item | Example entry |
|---|---|
| Categorical tokens in order | chart-1 #0072B2, chart-2 #D55E00, chart-3 #009E73, chart-4 #CC79A7 |
| Tokens allowed only with labels | chart-5 #E69F00, chart-6 #56B4E9 |
| Dark-mode equivalents | Each token re-checked on the dark plot color, with ratios recorded |
| Semantic colors | success, warning, danger, neutral, never reused as series colors |
| Line styles by meaning | actual solid, forecast dashed, target dotted, prior period dash-dot |
| Minimum stroke | 2px for lines, 1px dark outline for adjacent light fills |
| Text | Labels at 4.5:1 on their actual background, including inside bars |
| Alternatives | Every chart ships with a title, a summary sentence and a data table |
The design system guide explains how to publish tokens like these so product teams pull them from one source.
Common mistakes
- Checking series colors against white only when the product also ships a dark theme.
- Relying on a "colorblind-safe" label without measuring luminance. Several Okabe-Ito colors fail 3:1 on white as unlabeled lines.
- White gaps between light segments, which add almost no contrast against orange, sky blue or yellow fills.
- Hover-only values on dashboards that are mostly read on phones.
- Semantic drift: green meaning "good" on one chart and "Product C" on the next.
- Hiding the data table with
display: none, which also hides it from screen readers. - Gradient legends without numbers, which force readers to judge lightness differences unaided.
Frequently asked questions
Are red and green banned in charts?
No. WCAG forbids color as the only cue, not particular hues. Red and green can appear together when labels, icons, patterns or position carry the same meaning. Okabe and Ito's guidance is to prefer vermilion over pure red and to avoid relying on the red-green pair.
Do gridlines need 3:1 contrast?
W3C's guidance says data lines need not contrast with the graduated lines, and gridlines are usually a reading aid rather than required content. Keep them light enough not to compete with the data. If readers must read exact values from the grid with no labels, treat the gridlines as required and test them.
Does a heat map fail 1.4.11 because neighboring cells are similar?
Not necessarily. The 1.4.11 Understanding page says heat maps that represent a measurement can fall under the essential exception. Provide a numbered legend and a way to get each cell's value, such as a focusable cell with its value or a table view.
How many colors can a categorical palette safely hold?
There is no WCAG number. On white, the Okabe-Ito set yields only four colors that clear 3:1 as unlabeled lines, which is a practical ceiling for charts without labels. With direct labels or markers, more series can be told apart, but each extra line adds crossings and label collisions; as a rule of thumb rather than a standard, switch to small multiples once a single chart passes about six series.
Is a data table enough on its own?
A visible, well-marked-up table gives screen reader users the full data, but sighted readers still need the chart to work, so contrast and non-color cues still apply. The table complements the chart; it does not excuse it.
Reference list for the palette and contrast figures
- W3C, Web Content Accessibility Guidelines 2.2 (1.4.1, 1.4.3, 1.4.11, 1.4.13, contrast ratio and relative luminance definitions): https://www.w3.org/TR/WCAG22/, checked October 22, 2026
- W3C, Understanding SC 1.4.11 Non-text Contrast (graphs, pie charts, labels, gradients, thin lines): https://www.w3.org/WAI/WCAG22/Understanding/non-text-contrast.html, checked October 22, 2026
- W3C, Understanding SC 1.4.1 Use of Color (sales chart example, technique G111): https://www.w3.org/WAI/WCAG22/Understanding/use-of-color.html, checked October 22, 2026
- W3C WAI, Complex Images tutorial: https://www.w3.org/WAI/tutorials/images/complex/, checked October 22, 2026
- Okabe and Ito, Color Universal Design (prevalence figures, vermilion advice): https://jfly.uni-koeln.de/color/, checked October 22, 2026
- R Core Team, grDevices colorstuff.R source, Okabe-Ito hex values (via the wch/r-source GitHub mirror): https://raw.githubusercontent.com/wch/r-source/trunk/src/library/grDevices/R/colorstuff.R, checked October 22, 2026
- MDN, ARIA img role: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Roles/img_role, checked October 22, 2026
- MDN, forced-colors media feature: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/forced-colors, checked October 22, 2026
- Chrome for Developers, Apply effects with the Rendering tab (vision deficiency emulation): https://developer.chrome.com/docs/devtools/rendering/apply-effects, checked October 22, 2026
- Chrome for Developers, Emulate CSS media features (forced-colors): https://developer.chrome.com/docs/devtools/rendering/emulate-css, checked October 22, 2026
Contrast ratios in this guide were calculated by our editorial team with the WCAG 2.2 relative luminance formula; small differences from other tools come from rounding in their displays.
Your chart palette will only stay consistent if the surfaces under it are settled first. Our guide to dark surfaces and text tones is the next stop if your dashboard ships a dark theme, because every ratio in the table above changes when the plot background does.