WCAG contrast ratio on Mac: AA and AAA explained
Choose the applicable criterion and text size before reading the ratio. A checker can calculate one color pair; it cannot decide which WCAG row governs the implemented state.
For WCAG 2.2 text contrast, normal text needs at least 4.5:1 at Level AA or 7:1 at Level AAA. Large-scale text needs at least 3:1 at AA or 4.5:1 at AAA. WCAG defines large scale as at least 18 point regular or 14 point bold, with equivalent sizes for other fonts.
Choose the row from the implemented content, size, weight, and target level before reading a checker. Meaningful controls and graphics, inactive components, color-only information, and keyboard focus have different criteria or exceptions. Four text rows cannot settle those decisions.
Disclosure: I build TeenyTool. Its current local Contrast Checker reports the four text rows for one opaque foreground/background hex pair. The thresholds and criterion boundaries in this guide come from W3C WCAG 2.2.
This page owns the standards decision. The Mac color contrast checker guide covers the exact TeenyTool input and repeat-state workflow.
Quick answer: choose the row first
| Implemented content | Threshold or criterion | Decision note |
|---|---|---|
| Normal text | 4.5:1 AA; 7:1 AAA | Use this row unless the text meets the large-scale definition. |
| At least 18 point regular or 14 point bold | 3:1 AA; 4.5:1 AAA | Confirm rendered size and weight. A heading label alone does not make text large. |
| Meaningful control boundary, state, or graphic | 3:1 at AA where Success Criterion 1.4.11 applies | Compare the visual information needed to identify it against adjacent colors. |
| Inactive control | Exempt under 1.4.3 and 1.4.11 | Usability can still justify a discernible disabled state. |
| Keyboard focus | Focus Visible is AA; Focus Appearance is AAA | The AAA criterion adds indicator area and a 3:1 focused-versus-unfocused change. |
01Choose level, content, size, and weight
Start with the conformance target: Level AA or Level AAA. Then identify the content being tested. Text contrast, non-text contrast, use of color, and focus each answer a different accessibility question.
For text, get the rendered size and weight from the user agent or implementation. WCAG's large-scale definition is 18 point regular or 14 point bold, with equivalent sizes for other fonts. The Understanding document notes approximate CSS equivalents of 24px and 18.5px, while warning that thin or unusual fonts need care.
Write the chosen row before the number: normal text, Level AA or large-scale text, Level AAA. This prevents a 3:1 result from being called a pass merely because the checker displays a green large-text row.
02Use the owned foreground and background pair
Collect the foreground and background values that the implementation owns for the exact state. A label over a tinted card must be checked against that card, not the page behind it. A Dark Mode or selected state needs its own resolved pair.
Transparency, gradients, images, and materials cannot be represented by two opaque hex fields without resolving the effective colors first. Use the browser, app code, or an appropriate inspector to establish the pair and record any assumption about the backing layer.
A rendered screenshot is useful supporting evidence. It is a separate record because text antialiasing and capture handling alter pixels. The TeenyColor guide shows how to check Dark Mode colors from Mac screenshots without treating a sampled pixel as the source value.
03Know exactly what TeenyTool reports
TeenyTool's current source accepts three-digit or six-digit foreground and background hex values. It expands short hex, converts the pair to RGB, calculates relative luminance, and displays the contrast ratio.
The interface reports four fixed rows: AA normal at 4.5:1, AA large at 3:1, AAA normal at 7:1, and AAA large at 4.5:1. It shows sample text, but it does not ask for the implemented font size or weight and does not select the governing row.
The checker also does not accept alpha, composite transparency, inspect gradients or images, measure focus-indicator area, detect color-only meaning, or verify that the entered pair came from the right state. Resolve those questions outside the tool and keep them in the result record.
04Keep threshold math unrounded
WCAG ratios are thresholds. W3C explicitly says a computed 4.499:1 result does not meet 4.5:1. Preserve enough precision to make that decision before formatting the ratio for a report.
A 4.51:1 source pair does pass the 4.5:1 calculation. The standards result should stay accurate. A team can still choose a stronger pair to protect against later token changes or to improve the appearance of thin text, as long as the report distinguishes the requirement from that design margin.
For rendered text, W3C recommends the underlying foreground and background values for the formal calculation because user agents control font smoothing and antialiasing. Inspect the final rendering too, while keeping it separate from the source-pair result.
05Route non-text, focus, inactive, and color cues separately
Success Criterion 1.4.11 uses 3:1 at Level AA for the visual information needed to identify applicable user interface components, states, and graphical objects against adjacent colors. TeenyTool's four text rows do not report that criterion, even when the number happens to be the same as large-text AA.
Focus Visible is a Level AA requirement for a visible keyboard focus indicator. Focus Appearance is a separate Level AAA criterion with a minimum indicator area equivalent to a 2 CSS pixel perimeter and a 3:1 change between the same pixels in focused and unfocused states. One foreground/background pair cannot check the area requirement.
Inactive controls are exempt from the contrast requirements in 1.4.3 and 1.4.11. A design can still make disabled states easier to recognize for usability. Use of Color is a Level A criterion: when color conveys information or state, provide another visible cue where required. A strong ratio alone does not supply that cue.
WCAG contrast result record
Save enough context for another reviewer to repeat the decision:
- Build or route, component, content, interaction state, and appearance.
- Owned foreground and background values plus their source.
- Criterion, conformance level, text size, text weight, and normal or large classification when applicable.
- Unrounded ratio, reported result, and checker used.
- Transparency, image, gradient, material, or tool limitation.
- Rendered observation, color-only cue check, focus check, owner, and next action.
The Mac Dark Mode accessibility checklist combines this formal record with the paired-appearance and screenshot evidence needed for a full handoff.
Common row-selection mistakes
| Mistake | Why it breaks the check | Better move |
|---|---|---|
| Calling every heading large text | The semantic heading level does not establish its rendered size and weight. | Check the implemented font metrics against the large-scale definition. |
| Using the 3:1 large-text row for an icon | The number matches, but the applicable criterion and comparison are different. | Document non-text contrast and the adjacent colors being compared. |
| Rounding 4.499:1 to 4.5:1 | Threshold values cannot be rounded up into a pass. | Use the unrounded result for the decision. |
| Applying a text-row result to focus | The checker does not measure focus-indicator visibility or area. | Check Focus Visible and, when in scope, Focus Appearance separately. |
Sources checked
- TeenyTool behavior was checked against the TeenyTool homepage and current local Swift source for
ContrastCheckerView.swiftandColorMath.swift. - W3C Understanding Success Criterion 1.4.3: Contrast (Minimum) for text thresholds, large-scale text, exceptions, antialiasing, and unrounded comparisons.
- W3C Understanding Success Criterion 1.4.11: Non-text Contrast.
- W3C Understanding Success Criterion 1.4.1: Use of Color.
- W3C Understanding Success Criterion 2.4.7: Focus Visible and 2.4.13: Focus Appearance.
FAQ
What WCAG contrast ratio should normal text pass?
WCAG 2.2 sets the Level AA minimum for normal text at 4.5:1. Level AAA for normal text is 7:1.
When does large text use the 3:1 contrast ratio?
At Level AA, large-scale text can use the 3:1 threshold. WCAG defines large scale as at least 18 point regular or 14 point bold, with equivalent sizes for other fonts. Large-scale text uses 4.5:1 at Level AAA.
Does a contrast checker decide which WCAG row applies?
No. TeenyTool reports AA and AAA rows for normal and large text, but it does not read the interface or ask for font size and weight. Choose the criterion and text classification from the implemented state before treating a row as the result.
Does a passing contrast ratio guarantee accessible UI?
No. A passing pair does not prove visible focus, sufficient focus-indicator area, a non-color cue, correct semantics, keyboard behavior, or assistive technology support. It confirms only the tested pair against the chosen threshold.
Choose the row before reading the result.
Record the implemented state, owned pair, criterion, level, text classification, unrounded ratio, and remaining checks together.