auditmysitev2.0.2

Insufficient contrast for UI elements

contrast/control-undetermined

WCAG success criterion
1.4.11 (level AA)
Outcome class
Hint only. An automated check that by design reports review hints only: its findings are marked for manual review, never as confirmed violations.
Area
Accessibility, Visual Presentation
Default severity
medium
axe-core rule
non-text-contrast

Why we flag this

Interactive elements are hard to recognize.

Contrast ratio of UI elements below 3:1.

What the rule checks

Scope. Author-drawn controls (appearance: none) whose background behind the control cannot be resolved (gradient or image).

Expectation. Reports a review (UNTESTED) for an author-drawn control whose parent background is a gradient or image, instead of comparing against white. A control on a solid background is measured (pass or contrast/control-insufficient), never reported here.

Source. WCAG 2.2 SC 1.4.11 Non-text Contrast; a11y-rules rule 3 (not determinable is not a pass)

Detection: shared; needs dom, computed_style, geometry.

Failing example

The check flags this for review. Corpus case visual_control_contrast, element input#cb-gradient. The page may contain further findings for other rules.

visual_control_contrast.htmlHTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Custom checkbox and switch boundaries</title>
<style>
  body { background: #ffffff; color: #111111; }
  .custom { -webkit-appearance: none; appearance: none; width: 24px; height: 24px; margin: 0 8px 0 0;
            background: #ffffff; border: 2px solid #cccccc; vertical-align: middle; }
  #cb-ok { border-color: #767676; }
  #cb-edge-pass { border-color: #949494; }
  #cb-edge-fail { border-color: #959595; }
  .switch { display: inline-block; width: 64px; height: 44px; border: 2px solid #cccccc;
            border-radius: 22px; background: #ffffff; vertical-align: middle; }
  .gradient { display: block; padding: 8px; background-image: linear-gradient(90deg, #ffffff, #e8e8e8); }
  label { display: block; margin: 12px 0; }
</style>
</head>
<body>
<header>
  <a href="#main" style="display: inline-block; min-width: 44px; min-height: 44px; line-height: 44px; padding: 0 8px">Skip to main content</a>
  <p>Newsletter settings</p>
  <nav aria-label="Main"><a href="#main" aria-current="page" style="display: inline-block; min-width: 44px; min-height: 44px; line-height: 44px; padding: 0 8px">Overview</a></nav>
</header>
<main id="main">
  <h1>Notification preferences</h1>
  <form action="#">
    <!-- 1.61:1 against white: below the 3:1 a control boundary needs. -->
    <label><input type="checkbox" class="custom" id="cb-faint"> Weekly digest</label>
    <!-- 4.54:1: passes. -->
    <label><input type="checkbox" class="custom" id="cb-ok"> Product news</label>
    <!-- Threshold: 3.03:1 passes, 2.995:1 fails (no rounding up). -->
    <label><input type="checkbox" class="custom" id="cb-edge-pass"> Event invitations</label>
    <label><input type="checkbox" class="custom" id="cb-edge-fail"> Reminders</label>
    <!-- Native checkbox: drawn by the browser, no author boundary to measure. -->
    <label><input type="checkbox" id="cb-native"> Partner offers</label>
    <!-- Not rendered: nothing to measure. -->
    <label>Hidden option <input type="checkbox" class="custom" id="cb-hidden" style="display: none"></label>
    <!-- Background is a gradient: the colour behind the control is unknown. -->
    <label class="gradient"><input type="checkbox" class="custom" id="cb-gradient"> Surveys</label>
    <!-- ARIA switch drawn with a div: same 1.61:1 boundary. -->
    <p><span id="sw-label">Dark mode</span>
      <span id="sw-faint" class="switch" role="switch" aria-checked="false" aria-labelledby="sw-label" tabindex="0"></span></p>
    <button type="submit" style="min-width: 44px; min-height: 44px">Save preferences</button>
  </form>
</main>
<footer><p>Footer text</p></footer>
</body>
</html>

Passing example

The check passes here and reports nothing. Corpus case visual_control_contrast, element input#cb-faint. The page may contain further findings for other rules.

visual_control_contrast.htmlHTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Custom checkbox and switch boundaries</title>
<style>
  body { background: #ffffff; color: #111111; }
  .custom { -webkit-appearance: none; appearance: none; width: 24px; height: 24px; margin: 0 8px 0 0;
            background: #ffffff; border: 2px solid #cccccc; vertical-align: middle; }
  #cb-ok { border-color: #767676; }
  #cb-edge-pass { border-color: #949494; }
  #cb-edge-fail { border-color: #959595; }
  .switch { display: inline-block; width: 64px; height: 44px; border: 2px solid #cccccc;
            border-radius: 22px; background: #ffffff; vertical-align: middle; }
  .gradient { display: block; padding: 8px; background-image: linear-gradient(90deg, #ffffff, #e8e8e8); }
  label { display: block; margin: 12px 0; }
</style>
</head>
<body>
<header>
  <a href="#main" style="display: inline-block; min-width: 44px; min-height: 44px; line-height: 44px; padding: 0 8px">Skip to main content</a>
  <p>Newsletter settings</p>
  <nav aria-label="Main"><a href="#main" aria-current="page" style="display: inline-block; min-width: 44px; min-height: 44px; line-height: 44px; padding: 0 8px">Overview</a></nav>
</header>
<main id="main">
  <h1>Notification preferences</h1>
  <form action="#">
    <!-- 1.61:1 against white: below the 3:1 a control boundary needs. -->
    <label><input type="checkbox" class="custom" id="cb-faint"> Weekly digest</label>
    <!-- 4.54:1: passes. -->
    <label><input type="checkbox" class="custom" id="cb-ok"> Product news</label>
    <!-- Threshold: 3.03:1 passes, 2.995:1 fails (no rounding up). -->
    <label><input type="checkbox" class="custom" id="cb-edge-pass"> Event invitations</label>
    <label><input type="checkbox" class="custom" id="cb-edge-fail"> Reminders</label>
    <!-- Native checkbox: drawn by the browser, no author boundary to measure. -->
    <label><input type="checkbox" id="cb-native"> Partner offers</label>
    <!-- Not rendered: nothing to measure. -->
    <label>Hidden option <input type="checkbox" class="custom" id="cb-hidden" style="display: none"></label>
    <!-- Background is a gradient: the colour behind the control is unknown. -->
    <label class="gradient"><input type="checkbox" class="custom" id="cb-gradient"> Surveys</label>
    <!-- ARIA switch drawn with a div: same 1.61:1 boundary. -->
    <p><span id="sw-label">Dark mode</span>
      <span id="sw-faint" class="switch" role="switch" aria-checked="false" aria-labelledby="sw-label" tabindex="0"></span></p>
    <button type="submit" style="min-width: 44px; min-height: 44px">Save preferences</button>
  </form>
</main>
<footer><p>Footer text</p></footer>
</body>
</html>

This page is generated from the rule catalogue and the rule contracts; see therule overview for how the outcome classes are derived.