On each web page, are the colors used in interface components or in graphical elements conveying information sufficiently contrasted (except in special cases)?
A visually impaired user navigating by keyboard must be able to visually distinguish each interface component: a form field, a checkbox, a button, a chart. If the border of an input field blends into the page background, or if the colors of a pie chart are barely distinguishable from one another, these users lose information that others perceive effortlessly. This is the heart of this criterion.
The threshold is 3:1 minimum, measured between the color of the component or graphical element and the adjacent background color. This ratio applies to all states of the component: rest, hover, focus, active. A button that complies at rest but is unreadable on hover fails test 3.3.1.
For graphical elements, two measurements are needed: the color of the element against its background (test 3.3.2), and the internal colors of the element among themselves when they carry information (test 3.3.3). A line graph with two color-similar traces can pass the first test and fail the second.
If you provide a mechanism allowing the user to display an enhanced-contrast version, this mechanism itself must comply with the 3:1 ratio (test 3.3.4). A button that is unreadable for accessing high-visibility mode is the solution that blocks access to the solution.
4 tests to verify the contrast of interface components
Contrast of interface components
- Identify all visually distinct interface components: buttons, input fields, checkboxes, radio buttons, switches, tabs, etc.
- For each component, measure the contrast ratio between its distinctive color (border, background, visual indicator) and the adjacent background color.
- Test each state: rest, hover (
:hover), focus (:focus), active (:active), checked/selected. - Verify that each state reaches 3:1 minimum — or that a mechanism allows the user to display the component with this ratio.
- If all states of all components comply with the condition: test passed. A single non-compliant state is enough to fail the test.
Contrast of graphical elements on background
- Identify all information-carrying graphical elements: meaningful icons, graphs, pictograms, navigation arrows, curve traces.
- For each element, isolate the visual parts necessary for its understanding.
- Measure the contrast ratio between these colors and the directly adjacent background color.
- Verify that the ratio reaches 3:1 minimum — or that an alternative mechanism is proposed.
- Purely decorative elements, logos, and elements whose presentation is intrinsic to the information (flag, photo) are excluded from the test.
Contrast between adjacent colors of a graphical element
- Identify graphical elements whose understanding relies on distinguishing multiple internal colors: pie charts, multiple curves, color legends, choropleth maps.
- For each pair of contiguous colors that carries information (e.g., two adjacent segments of a pie chart), measure their contrast ratio to each other.
- Verify that each pair reaches 3:1 minimum — or that an alternative mechanism exists.
- Non-contiguous colors do not need to be compared to each other, only colors that touch directly.
Contrast of enhanced contrast mechanism
- Identify on the page all mechanisms proposed to improve contrast: "high visibility mode" buttons, theme selectors, enhanced contrast switches.
- For each mechanism, analyze its own visual components and graphical elements carrying information.
- Verify that these components themselves comply with a 3:1 minimum ratio.
- If all mechanisms are themselves readable: test passed. A high-visibility mode button that does not comply with the 3:1 ratio fails the test.
Examples
❌ Non-compliant : Material Design input field with insufficient border
<div style="background: #FFFFFF; padding: 20px;">
<div style="
background: #F5F5F5;
border-bottom: 1px solid #E0E0E0;
padding: 10px;
">
<label for="email" style="color: #999999; font-size: 12px;">Email address</label>
<input id="email" type="email" style="
background: transparent;
border: none;
color: #000000;
width: 100%;
">
</div>
</div>The very light gray background (#F5F5F5) on white (#FFFFFF) produces a 1.1:1 ratio. The bottom border (#E0E0E0) on white reaches 1.2:1. A visually impaired user cannot perceive the field boundaries and does not know where to enter their value. This Material Design "filled" pattern is very widespread and almost systematically non-compliant.
✅ Compliant : Input field with contrasted border
<div style="background: #FFFFFF; padding: 20px;">
<label for="email" style="display: block; color: #000000; margin-bottom: 4px;">
Email address
</label>
<input id="email" type="email" style="
background: #FFFFFF;
border: 2px solid #666666;
color: #000000;
padding: 8px 12px;
width: 100%;
box-sizing: border-box;
">
</div>The dark gray border (#666666) on white background (#FFFFFF) reaches 5.7:1, well above the 3:1 threshold. The field perimeter is clearly visible to all users, including those with reduced contrast sensitivity. The entered text (#000000) also complies with criterion 3.2.
❌ Non-compliant : Button with non-compliant hover states
<style>
.btn {
background-color: #FFFFFF;
border: 2px solid #000000;
color: #000000;
padding: 8px 16px;
}
.btn:hover {
background-color: #DDEEFF;
border: 2px solid #4A90E2;
color: #000000;
}
</style>
<button class="btn">Submit</button>At rest, the button is compliant: black border on white background = 21:1. On hover, the blue border (#4A90E2) on very light blue background (#DDEEFF) produces a 1.8:1 ratio, below the threshold. Test 3.3.1 fails because all states must be compliant, not just the rest state.
✅ Compliant : Line graph with distinction by pattern and color
<svg viewBox="0 0 300 150" role="img" aria-label="Sales 2025: product A up, product B stable">
<title>Sales 2025: product A up, product B stable</title>
<!-- Product A curve: dark blue, solid stroke -->
<polyline
points="10,120 80,80 150,50 220,30 290,20"
fill="none"
stroke="#1A56A0"
stroke-width="3"
/>
<!-- Product B curve: dark orange, dashed stroke -->
<polyline
points="10,100 80,95 150,98 220,92 290,96"
fill="none"
stroke="#C05A00"
stroke-width="3"
stroke-dasharray="6,4"
/>
</svg>Both stroke colors (#1A56A0 and #C05A00) each have a ratio greater than 3:1 against the white background. Contiguous traces also have sufficient ratio between them. As a bonus, distinct patterns (solid vs dashed) allow colorblind users to differentiate curves without relying solely on color.
Tips and pitfalls
⚠️ Testing only the rest state
The most frequent auditing error: measuring component contrast at rest and ignoring other states. RGAA requires 3:1 for each state: hover, focus, active, selected, checked. A form field with a nice gray border at rest can display a light blue border on focus that does not pass the threshold. Test with DevTools by forcing each CSS pseudo-class.
⚠️ Confusing criterion 3.2 and criterion 3.3
Criterion 3.2 concerns text (threshold 4.5:1 for normal text, 3:1 for large text). Criterion 3.3 concerns interface components and graphical elements (threshold 3:1 in all cases). A button with text must comply with both: 3.2 for the contrast between text and button background, 3.3 for the contrast between border and page background. Both can fail independently.
⚠️ Inactive components: exempt, not ignored
A component with the disabled attribute is exempt from criterion 3.3. Low contrast is moreover often intentional to signal unavailability. But beware: if you simulate a disabled state with CSS without disabled (example: pointer-events: none on a <button>), the exemption does not apply. The component must be genuinely inactive from the browser's perspective.
⚠️ Browser native styles: unmodified, not audited
If you have applied no CSS style to a native component (<input>, <select>, <button>), its appearance is the browser's responsibility and the criterion does not apply. As soon as you touch border, background, outline or box-shadow, you assume responsibility for contrast. Many teams think they are covered by browser styles when a single border: none in a CSS reset is enough to make the criterion applicable.
💡 The border is not always mandatory
According to the "Boundaries" exception in WCAG 1.4.11, if the text inside a button is sufficient to visually identify the component and its state, the border does not need to reach 3:1 against the background. A <button> with a colored background and white text complying with criterion 3.2 is compliant with criterion 3.3 even without a visible border. It is counter-intuitive, but documented in WCAG.
⚠️ Dynamic graphical elements: the hover state can save an insufficient rest state
This is one of the rare asymmetries of RGAA: a graphical element whose contrast is insufficient at rest but sufficient on hover and focus can be declared compliant for criterion 3.3. The reverse is not true for interface components (test 3.3.1), where all states must be compliant. This exception only concerns graphical elements (tests 3.3.2 and 3.3.3).
💡 Measuring contiguous colors in graphs
For a pie chart, it is not enough to measure each color against the white background. You must also measure each pair of colors that touch each other. Two orange and yellow segments can be readable individually against the background but indiscernible from each other (ratio less than 3:1). Use Includdy to measure directly adjacent pixels.
Frequently asked questions
What exact part of a button must comply with the 3:1 contrast ratio in RGAA?
This depends on what visually identifies the button. If the button has a colored background without a border, it is the button background against the page background. If the button has a border as the only visual indicator, it is the border against the page background. If the text is sufficient to identify the component ("Boundaries" exception), the 3:1 ratio for the border is not required — but criterion 3.2 still applies to the text.
How to audit the contrast of inline SVG icons according to RGAA criterion 3.3?
Measure the contrast between the icon's fill color (fill) or stroke color (stroke) and the adjacent background color. Use the DevTools color picker directly on the pixels rendered on screen — CSS variables or inherited values can differ from the final color. If the icon is purely decorative and accompanied by equivalent text, it is exempt.
In what cases is a graph with a text legend exempt from RGAA criterion 3.3?
Partially. If the information conveyed by the graph's colors is entirely available in text visible on the page (data table, description in the body text), the graphical parts concerned are exempt from criterion 3.3. But if the legend merely names the series without giving values, the colors remain information-carrying and the criterion applies.
How to assess the contrast of a site's dark mode according to RGAA criterion 3.3?
Yes. If your site provides a light/dark theme selector, each theme must comply with criterion 3.3 independently. The selector itself is a mechanism within the meaning of test 3.3.4: its graphical components must reach 3:1. The system-preferred color scheme (prefers-color-scheme) does not exempt you from verifying contrast in each mode activatable by the user.
What difference exists between RGAA criteria 3.2 and 3.3 for form field placeholders?
By criterion 3.2, because placeholder text is text. The applicable threshold is 4.5:1 for normal text (or 3:1 if the size exceeds 24px or 18.66px bold). Criterion 3.3 applies to the field's border or background, not the text it contains. Both can fail on the same field for different reasons.