Accessible Candlestick and Financial Charts

Permalink to "Accessible Candlestick and Financial Charts"

Candlestick and OHLC charts are the standard view of prices in trading, treasury and crypto products. Each candle encodes four values — open, high, low, close — plus direction (green up, red down) in a few pixels. That density is useful for experienced traders and hostile to everyone else: colour-blind users cannot tell red from green, screen reader users get nothing, and even sighted keyboard users cannot read exact values without hovering.

This guide belongs to chart type-specific patterns.

Spec reference

Permalink to "Spec reference"
  • SC 1.4.1 Use of Color (A) — green and red as the only up and down cue fails; use hollow and filled candles (a long-standing convention) or arrows.
  • SC 1.1.1 Non-text Content (A) — a summary of the range and a table of periods.
  • SC 2.1.1 Keyboard (A) — candle details (OHLC) shown on hover must be available by keyboard.
  • SC 1.4.11 Non-text Contrast (AA) — candle bodies and wicks against the background at 3:1.
  • SC 2.2.2 Pause, Stop, Hide (A) — live-updating price charts need a pause control if they update automatically alongside other content.
A period table for a candlestick chart Table mock with Date, Open, High, Low, Close and Change columns for four days; the down day is flagged and one cell focused. A period table for a candlestick chartDateOpenHighLowCloseChange29 Sep101.2103.0100.8102.6+1.4 up30 Sep102.6104.1102.0103.9+1.3 up1 Oct103.9104.099.5100.2−3.7 down2 Oct100.2101.899.9101.5+1.3 up
Direction appears as a signed change and a word, not just a colour.

When to use — and when not to

Permalink to "When to use — and when not to"

Use candlesticks for audiences who need intraperiod ranges — traders, analysts. For general audiences, a line chart of closing prices with a summary is easier for everyone, and much easier to make accessible.

Do not rely on red and green alone, and do not hide OHLC values behind hover. The misapplication: a crypto dashboard with red and green candles, hover-only tooltips and a live feed that updates every second with no pause.

Colour-only candles versus accessible candles Comparison: colour-only candles fail colour-blind users and hide values behind hover; accessible candles use hollow and filled bodies, announce OHLC on focus and offer a table and summary. Colour-only candles versus accessible candles✗ Red and green onlyValues on hoverNo summaryLive updates, no pause✓ Hollow up, filled down, plus colourOHLC on focus and in a table"Up 4.2% over 30 days; range 96.1 to 104.1"Pause control; summaries at intervals

Annotated code example

Permalink to "Annotated code example"
<figure aria-labelledby="c-t" aria-describedby="c-s">
  <h3 id="c-t">ACME daily prices, last 30 days</h3>
  <p id="c-s">Closed at 101.5, up 4.2% over 30 days. High 104.1 (30 Sep), low 96.1 (12 Sep). 18 up days, 12 down days.</p>
  <svg viewBox="0 0 20 20" role="application" aria-label="Candlestick chart, daily. Left and Right move between days." tabindex="0">…</svg>
  <p id="c-status" role="status" class="visually-hidden"></p>
</figure>
let i = data.length - 1;                                   // start at the latest period
svg.addEventListener('keydown', (e) => {
  const step = { ArrowLeft: -1, ArrowRight: 1, PageUp: -5, PageDown: 5 }[e.key];
  if (e.key === 'Home') i = 0; else if (e.key === 'End') i = data.length - 1;
  else if (step) i = clamp(i + step, 0, data.length - 1); else return;
  e.preventDefault();
  const d = data[i], change = d.close - d.open;
  highlight(i);                                            // crosshair + outline (SC 2.4.7)
  status.textContent = `${fmtDate(d.date)}: open ${d.open}, high ${d.high}, low ${d.low}, close ${d.close}, ` +
    `${change >= 0 ? 'up' : 'down'} ${Math.abs(change).toFixed(1)}`;   // direction in words (SC 1.4.1)
});
/* Up candles hollow, down candles filled — direction without colour (SC 1.4.1) */
.candle.up   rect { fill: #ffffff; stroke: #155c38; stroke-width: 1.5; }
.candle.down rect { fill: #8a6000; stroke: #8a6000; }

Keyboard & AT behaviour

Permalink to "Keyboard & AT behaviour"
Key Action Expected announcement AT deviations
Tab Focus chart (latest day) Chart name, then latest period OHLC —
Left / Right Previous / next day “1 October: open 103.9, high 104.0, low 99.5, close 100.2, down 3.7” —
Page Up / Down Five days Same format —
Home / End First / last day Same format —
Information per period and where it appears Matrix of facts — open, high, low, close, direction, volume — against the candle drawing, focus announcement and table. Information per period and where it appearsCandle drawingFocus announcementTableOpen and closeBody edgesYesYesHigh and lowWick endsYesYesDirectionColour and fillWordSigned change and wordVolumeSeparate barsOptionalColumn
Every value in a candle appears in text somewhere.

Integration context

Permalink to "Integration context"

Keyboard navigation follows the line chart model in adding keyboard navigation to SVG line charts. Live price feeds are covered in ticker and price feed announcements and pause, stop, hide controls for auto-updating data. Range selection on long histories follows time range selectors for time series.

Gotchas

Permalink to "Gotchas"

Locale conventions. In some markets red means up. Use words and fill styles so meaning never depends on a colour convention.

Gaps. Non-trading days are gaps; announce them (“Weekend, no trading”) or skip them consistently.

Indicators. Moving averages and bands overlaid on candles need their own names in announcements (“20-day average 101.0”).

Common mistakes

Permalink to "Common mistakes"
  • Green and red as the only direction cue.
  • OHLC in hover tooltips only.
  • No summary of the visible range.
  • Live updates with no pause.

Framework notes

Permalink to "Framework notes"

Highcharts Stock with the accessibility module supports keyboard navigation of points; set accessibility.point.descriptionFormatter to output OHLC and direction. TradingView Lightweight Charts render to canvas with no accessibility layer — maintain a table and an announcer from your data. ECharts candlestick series support aria descriptions and custom item styles for hollow bodies.

// Highcharts Stock: OHLC with direction in words
accessibility: { point: { descriptionFormatter: p => `${Highcharts.dateFormat('%e %B', p.x)}: open ${p.open}, high ${p.high}, low ${p.low}, close ${p.close}, ${p.close >= p.open ? 'up' : 'down'}` } }

Worked example

Permalink to "Worked example"

A treasury team’s FX dashboard showed candlesticks in red and green on canvas. A colour-blind analyst routinely misread down days, and a screen reader user could not use the chart at all. The team switched to hollow and filled bodies, added keyboard navigation with OHLC announcements, a 30-day summary at the top, and a period table below with change in words and numbers. They also added a pause button to the live intraday view, which several sighted users said they had wanted for a long time.

Writing the summary

Permalink to "Writing the summary"

Financial users want the same facts from every price chart, in the same order: the latest close, the change over the visible period in absolute and percentage terms, the high and low with dates, and the balance of up and down periods. Keep the order fixed across charts so users can compare instruments by ear. If an event explains a move (an earnings date, a rate decision), add it in a final short sentence.

Testing checklist

Permalink to "Testing checklist"

Design system notes

Permalink to "Design system notes"

Define candle tokens for up and down with fill style and colour, verified at 3:1 in both themes and forced colours. Provide a financial chart wrapper with OHLC announcements, summaries and tables built in.

FAQ

Permalink to "FAQ"
Should I use candlesticks for general audiences?

Usually not. A line of closing prices with a summary is clearer and easier to make accessible.

Is hollow versus filled enough without colour?

Yes; it is a traditional convention and works in greyscale and forced colours. Keep colour as a secondary cue.

How should volume be announced?

As part of the period announcement if users need it (“volume 1.2 million”), and as a table column.

How do I summarise a long history?

Start, end, change and percentage change, highest and lowest with dates, and count of up and down periods.

What about intraday charts that update live?

Pause control, summaries at intervals, and no per-tick announcements. See the ticker guidance.

Should indicator lines be focusable?

Include their values in the period announcement rather than making them separate stops.

How do I make comparison charts (two instruments) accessible?

Normalise both to a start of 100 or to percentage change, announce both values per period (“ACME 104, Index 101”), and summarise the difference over the range.

Permalink to "Related"

← Back to Chart Type-Specific Patterns