contrast-enhanced

Text meets enhanced color contrast (AAA)

automaticWCAG 1.4.6 (AAA)confidence: highseverity: seriousperceivable

Checks that visible text has a contrast ratio of at least 7:1 (normal) or 4.5:1 (large), when contrast is computable from CSS.

Applies to. Applies to the visible text contrast-computable applies to, see that rule for the eligibility gates, narrowed to text whose background and foreground are actually computable. Eligible text that is not computable leaves this rule notApplicable rather than cantTell: reporting that uncertainty belongs to contrast-computable, so the two never report the same text twice.

Expectation. Every computable text node reaches the ratio SC 1.4.6 requires for its size: 4.5:1 for large text, 7:1 for everything else. Text is large at 24px or more, or at 14pt (about 18.667px) or more when the computed font weight is 700 or higher. Text drawn by a -webkit-text-stroke or a text-shadow is left to contrast-computable, except where every color it is drawn in, its fill among them unless the fill draws nothing (transparent, or the color of its background), is below the ratio against a flat background: no reading of it can then meet the criterion, and it fails, measured by the best of those colors (drawnBy: textStroke or textShadow). Margin (contrast-ratio): of the text that reaches its ratio, the element closest to it, with the ratio unrounded against the one its size requires; context.largeText says which. Only text within 10% of its ratio counts as close, so text further above it gives no margin. measuredCount counts the elements whose contrast was computed. Text part of which a ::first-line or ::first-letter paints in a color of its own is measured in both colors: where both reach their ratio it passes, where both fall short it fails (pseudoElementColor names the pseudo-element), and where they disagree it is left to contrast-computable. Text with no opaque background behind it, up to the root, is measured on the canvas the browser paints under the page, in the color scheme the page is drawn in, and, on a page that supports light and dark, in the other where its colors can't change with the scheme, as contrast-minimum describes. Normal-size text whose background can't be worked out still fails when its color can't reach 7:1 on any background (CONTRAST_UNREACHABLE_ANY_BACKGROUND, metrics.bestRatio: its ratio against white or black, whichever is higher). A field's placeholder below its ratio (PLACEHOLDER_BELOW_THRESHOLD) fails when the page chose its colors: the placeholder's color, opacity or background, or the field's background, differ from the browser's own, read in a blank frame. A placeholder left in the browser's own colors is taken to meet the ratio (WCAG G148), and when that can't be told it is a cantTell occurrence.

What a finding reports.

  • metrics.ratio (a FAIL): the text's contrast ratio, for example 4.5 for 4.5:1, unrounded, against metrics.threshold (7, or 4.5 for large text).
  • colors.foregroundHex, colors.backgroundHex (a FAIL): the text and background colors the ratio was computed from, as hex (the text in the -webkit-text-fill-color it is painted in, color unless set). A semi-transparent text color is first blended onto the background.
  • selectField (a drop-down select in the browser's own background): backgroundHex, its computed background, and fieldHex, the Field color Chromium paints it in. The text is measured against both and the lower ratio is reported.
  • colors.foregroundRgba, colors.backgroundRgba (a FAIL): the same colors as rgba() strings.
  • typography.fontSizePx, typography.fontSizePt (a FAIL): the font size as drawn (the computed size times CSS zoom, or for SVG text its viewBox and transform scale, and times what font-size-adjust scales the font by), in CSS pixels and in points.
  • typography.declaredFontSizePx, typography.sizeScaledBy (a FAIL drawn at another size): the computed font-size, and what drew it otherwise (zoom, svg, font-size-adjust). Where that puts the text on the other side of the large-text line, the hint says so (contrast_hint_drawnSize).
  • typography.fontWeight, typography.fontWeightLabel, typography.isBold (a FAIL): the computed font weight as a number, bold (700 or more) or normal, and whether it counts as bold.
  • typography.isLargeText (a FAIL): whether the text counts as large, which sets the threshold.
  • The ratio, threshold and typography fields above are a stable contract, unlike the rest of data.details.
  • assumptionsApplied, assumedRootCanvasColor (a FAIL): null unless the page background never became opaque and was taken to sit on a canvas color: one the scan names (contrast.rootCanvasFallback), or, with the auditorAssist mode where the page's own canvas can't be known (in a frame, under forced colors), the fallback. Then assumptionsApplied is ["ROOT_CANVAS_FALLBACK"] and assumedRootCanvasColor is that color. Text on the canvas the page's color scheme gives it is measured on that canvas, with neither.
  • colorScheme (a FAIL on the canvas of a page that supports light and dark): 'light' or 'dark', the scheme in which the text falls short, where it passes in the other; absent where it falls short in every scheme measured.
  • colorSchemesChecked (a FAIL, and the pass): the schemes the text on the canvas was measured in, where the page supports both and one could not be measured.
  • generatedBy (a FAIL on generated text): ::before, ::after or ::marker, the pseudo-element whose text is measured; the selector names its element, and the colors and font are the pseudo-element's.
  • eligibleTextCount, computableTextCount (the pass, and the result's own data.details when it is notApplicable because no text was computable, which lists no occurrence): how many text nodes were in scope, and how many of those had colors that could be worked out. The pass repeats both under metrics.
  • forcedColors (every occurrence, and that notApplicable result's details, when the colors measured were forced): true, and the hint says to check the page again with forced colors off. A scan under forced colors measures the page's own colors, so this is there only where it could not keep the page in them.

These data.details fields help to read and reproduce a finding. Apart from reasonCode and the few fields Output schema names as stable, they are not a stable contract: a field may be renamed or dropped in a minor release, so don’t build on them.

Margin. This rule measures contrast-ratio as a ratio, and the value must reach the threshold. When a pass came near the threshold, the result’s margin names the element that came closest while still meeting it, so a pass that a small change would flip shows before it flips. Unlike the fields a finding reports, it is a stable contract. See Output schema.

Examples

pass
<p style="background:#ffffff; color:#000000;">Body text</p>

Black on white is roughly 21:1, well above the AAA 7:1 threshold.

fail
<p style="background:#ffffff; color:#767676;">Body text</p>

Gray on white is about 4.6:1 — passes the AA minimum but fails the stricter 7:1 AAA threshold.

How to check

When this rule can’t decide, it reports cantTell and leaves the question to a person. Each question it can ask is listed here under its reason code, with the steps to answer it. A finding carries the same steps as howToCheck, in the scan’s language. See Output schema.

CONTRAST_UNREACHABLE_ANY_BACKGROUND

  1. Find the text the report names and note its color, which the report gives.
  2. With a contrast calculator, measure that color against white and against black.
  3. Compare the higher of the two ratios with 7:1.

Pass. Against white or black the text color reaches 7:1, so some background can bring it to the ratio; measure it then against its own background.

Fail. Against both white and black the text color stays below 7:1, so no background brings it to the ratio, which fails WCAG 1.4.6.

ENGINE_EXCEPTION

  1. Find the text the report names (the check stopped early, so nothing was measured).
  2. Use the color picker in the browser's developer tools, or a contrast calculator with colors picked by an eyedropper, to measure the text color against the background directly behind the letters.
  3. Note the text size and weight and compare the ratio with 7:1 (4.5:1 for large text: at least 24px, or 18.66px and bold).

Pass. The ratio reaches the threshold for its size.

Fail. The ratio is below the threshold for its size, which fails WCAG 1.4.6.

PLACEHOLDER_BELOW_THRESHOLD

  1. Find the field the report names and empty it so the placeholder shows.
  2. In the Styles pane, check whether the page's CSS sets the ::placeholder color or opacity, or the field's background.
  3. Use the color picker in the browser's developer tools, or a contrast calculator with colors picked by an eyedropper, to measure the placeholder text against the field background and compare with 7:1 (4.5:1 for large text: at least 24px, or 18.66px and bold).
  4. Check whether the placeholder holds information needed to fill the field (a format or instruction), rather than just an example.

Pass. The placeholder reaches 7:1 (or 4.5:1 if large), or it is drawn entirely in the browser's own default colors.

Fail. The page sets the placeholder or field colors and the ratio is below the threshold, which fails WCAG 1.4.6.

SYMBOLIC_CHARACTER_BELOW_THRESHOLD

  1. Find the character the report names (such as ×, ☰, › or an icon-font glyph).
  2. Decide whether it is text people read (part of words, a number) or an icon standing in for an action, like a close or menu symbol.
  3. If it is text, use the color picker in the browser's developer tools, or a contrast calculator with colors picked by an eyedropper, to measure it against its background and compare with 7:1 (4.5:1 for large text: at least 24px, or 18.66px and bold).
  4. If it is an icon, check first whether visible text next to it says the same thing, such as the word "Close" beside a close symbol. If it does, the icon is not the only way to understand it and does not need the 3:1 ratio.
  5. Otherwise, measure the icon against its background and compare with 3:1, the ratio for graphical objects.

Pass. It is text and reaches its ratio, or it is an icon that reaches 3:1 or whose meaning is also given by visible text next to it.

Fail. It is text below 7:1, which fails WCAG 1.4.6; or an icon below 3:1 that is the only visible way to know what it means or does, which fails WCAG 1.4.11.

View source