Other Occurrences — Text Colour Contrast
When the same text contrast problem appears many times on a page, the report publishes one representative finding and lists the rest underneath it as other occurrences. This page explains what has to match for two findings to be treated as the same problem.
What makes two findings the same
Every colour contrast finding is filed under a key made of exactly three things:
- the colour family of the foreground (the text),
- the colour family of the background,
- the text size category, either Normal or Large.
Foreground and background are not compared by their exact hex value. Each is sorted into a normalised colour family (see the table below). Two colours in the same family are treated as equivalent for grouping.
If any one of those three values differs, it is a different problem and gets its own group.
The two colours
Both colours are read from the element as the browser finally renders it, and rewritten into one standard notation before being used. That way rgb(255,255,255), #FFF and #ffffff all resolve to the same value and are correctly recognised as identical. Transparency is discarded — it is not a differentiator for grouping.
The text size category
Each element is classified using the WCAG thresholds:
- Large: 18pt (24px) or more at any weight, or 14pt (18.67px) or more when bold (font weight 700 or heavier).
- Normal: everything else.
Two elements with the same colour pair but a different size category are not grouped together, because they are held to different contrast requirements — 4.5:1 for normal text, 3:1 for large text.
How hover and focus fit in
Interaction states — normal, hover and focus — are not part of the grouping key. They are resolved before grouping happens:
- For each element, the tool checks whether hovering or focusing changes its colours compared with the default state.
- If a state introduces a different colour combination, it becomes its own finding, with its own foreground, background and size key — which may or may not match an existing group.
- If hover and focus produce the same colour combination as each other, or as the normal state, they are merged into a single finding before grouping runs. The state labels ("on hover", "on focus") are preserved in the finding's description, but they do not affect which group it lands in.
The practical result: a state change only creates a new group when it genuinely introduces new colours.
Example. A link whose normal state fails, and whose hover and focus states share one identical failing combination, produces two issues: one for Normal, and one grouped issue covering hover and focus together.
How the group is assembled
Once every finding has its key:
- The first finding for a given key becomes the main issue. It provides the title, the description and the representative element for the report.
- Every later finding with the same key is attached to that main issue as an additional occurrence, keeping its own location on the page and its own description, so each instance can still be found individually.
The colour families
Before grouping, each foreground and background value is converted to hue, saturation and lightness and sorted into one of these 12 families. Two different hex values that land in the same family are treated as equivalent.
| Family | Hue range | Saturation | Lightness | Representative examples |
|---|---|---|---|---|
| black | any | any | < 0.12 | #000000, #1a1a1a |
| white | any | any | > 0.90 | #ffffff, #f5f5f5 |
| gray | any | < 0.12 | 0.12 – 0.90 | #808080, #a0a0a0, #555555 |
| brown | 10 – 45° | ≥ 0.12 | 0.12 – 0.42 (*) | #8b4513, #a0522d |
| red | 0 – 10° and 345 – 360° | ≥ 0.12 | 0.12 – 0.90 | #ff0000, #cc3333, #e60026 |
| orange | 10 – 45° | ≥ 0.12 | 0.42 – 0.90 | #ff8c00, #e67e22, #f39c12 |
| yellow | 45 – 70° | ≥ 0.12 | 0.12 – 0.90 | #ffff00, #ffd700, #f1c40f |
| green | 70 – 165° | ≥ 0.12 | 0.12 – 0.90 | #00ff00, #2ecc71, #228b22 |
| cyan | 165 – 195° | ≥ 0.12 | 0.12 – 0.90 | #00ffff, #00ced1, #20b2aa |
| blue | 195 – 265° | ≥ 0.12 | 0.12 – 0.90 | #0000ff, #3498db, #1e90ff |
| purple | 265 – 310° | ≥ 0.12 | 0.12 – 0.90 | #800080, #9b59b6, #8e44ad |
| pink | 310 – 345° | ≥ 0.12 | 0.12 – 0.90 | #ff69b4, #e91e90, #ff1493 |
(*) Brown shares its hue range with orange (10–45°) and is distinguished by low lightness. Below 0.42 it is brown; at 0.42 or above it is orange.
Order of evaluation
- Extreme lightness: below 0.12 → black. Above 0.90 → white.
- Low saturation: below 0.12 → gray.
- Brown versus orange: hue 10–45° with lightness below 0.42 → brown; 0.42 or above → orange.
- Everything else: the family is assigned from the hue ranges in the table.
Why this matters
With this normalisation the grouping key changes from an exact colour match to a family match. Elements whose colours are visually similar but written as slightly different hex values — #cc3333 and #e60026, both reds — are grouped into the same issue instead of producing two near-identical findings.
