Skip to main content
Accessibility Testing·Lesson 2 of 5

WCAG Guidelines

The Web Content Accessibility Guidelines (WCAG) are the international standard for web accessibility. Published by the W3C, WCAG defines specific, testable criteria that determine whether web content is accessible.

WCAG Conformance Levels

WCAG has three conformance levels, each building on the previous:

LevelDescriptionTypical Requirement
AMinimum accessibilityLegal baseline
AAAddresses major barriersIndustry standard target
AAAHighest level of accessibilityAspirational, not required

Most organizations aim for WCAG 2.2 Level AA compliance. This is the standard referenced by most accessibility laws worldwide.

Key Success Criteria by Category

Text Alternatives (1.1)

Every non-text element needs a text alternative.

<!-- SC 1.1.1 Non-text Content (Level A) -->

<!-- Informative image: describe the content -->
<img src="team-photo.jpg" alt="Development team at the 2026 company retreat" />

<!-- Functional image: describe the function -->
<button>
  <img src="search-icon.svg" alt="Search" />
</button>

<!-- Complex image: provide detailed description -->
<figure>
  <img src="architecture-diagram.png" alt="System architecture diagram" aria-describedby="arch-desc" />
  <figcaption id="arch-desc">
    The system consists of a React frontend connecting to a Node.js API server,
    which communicates with a PostgreSQL database and Redis cache.
    A CDN sits in front of the frontend for static asset delivery.
  </figcaption>
</figure>

<!-- CAPTCHA: provide alternative -->
<div>
  <img src="captcha.png" alt="CAPTCHA verification" />
  <a href="/audio-captcha">Audio alternative</a>
</div>

Adaptable Content (1.3)

Content structure must be programmatically determinable.

<!-- SC 1.3.1 Info and Relationships (Level A) -->

<!-- Use semantic HTML for structure -->
<header>
  <nav aria-label="Main navigation">
    <ul>
      <li><a href="/">Home</a></li>
      <li><a href="/about">About</a></li>
    </ul>
  </nav>
</header>

<main>
  <h1>Page Title</h1>
  <section aria-labelledby="section-heading">
    <h2 id="section-heading">Section Title</h2>
    <p>Content here.</p>
  </section>
</main>

<!-- Use proper table markup -->
<table>
  <caption>Monthly Sales Report</caption>
  <thead>
    <tr>
      <th scope="col">Month</th>
      <th scope="col">Revenue</th>
      <th scope="col">Growth</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">January</th>
      <td>$50,000</td>
      <td>+12%</td>
    </tr>
  </tbody>
</table>

Distinguishable Content (1.4)

Make it easy for users to see and hear content.

/* SC 1.4.3 Contrast (Minimum) - Level AA */
/* Normal text: 4.5:1 contrast ratio */
/* Large text (18pt+ or 14pt bold): 3:1 contrast ratio */

/* Bad: insufficient contrast */
.low-contrast {
  color: #999999;           /* Gray on white = 2.85:1 */
  background-color: #ffffff;
}

/* Good: sufficient contrast */
.high-contrast {
  color: #595959;           /* Darker gray on white = 7:1 */
  background-color: #ffffff;
}

/* SC 1.4.4 Resize Text - Level AA */
/* Text must be resizable to 200% without loss of content */
/* Use relative units, not fixed pixels */

/* Bad */
.fixed-text {
  font-size: 14px;
  line-height: 18px;
  width: 400px;
}

/* Good */
.flexible-text {
  font-size: 0.875rem;
  line-height: 1.5;
  max-width: 40ch;
}

/* SC 1.4.11 Non-text Contrast - Level AA */
/* UI components and graphics need 3:1 contrast */

/* Bad: light border on input */
.input-low {
  border: 1px solid #cccccc; /* 1.6:1 against white */
}

/* Good: visible border */
.input-good {
  border: 1px solid #767676; /* 4.54:1 against white */
}

Keyboard Accessible (2.1)

All functionality must be available via keyboard.

<!-- SC 2.1.1 Keyboard (Level A) -->

<!-- Test keyboard navigation order -->
<!-- Tab moves forward, Shift+Tab moves backward -->
<!-- Enter/Space activates buttons and links -->
<!-- Arrow keys navigate within widgets (tabs, menus, radio groups) -->

<!-- Custom keyboard navigation for a tab component -->
<div role="tablist" aria-label="Course sections">
  <button
    role="tab"
    id="tab-1"
    aria-selected="true"
    aria-controls="panel-1"
    tabindex="0"
  >
    Overview
  </button>
  <button
    role="tab"
    id="tab-2"
    aria-selected="false"
    aria-controls="panel-2"
    tabindex="-1"
  >
    Lessons
  </button>
  <button
    role="tab"
    id="tab-3"
    aria-selected="false"
    aria-controls="panel-3"
    tabindex="-1"
  >
    Reviews
  </button>
</div>

<div role="tabpanel" id="panel-1" aria-labelledby="tab-1">
  Overview content here.
</div>
// Keyboard handler for tab component
tablist.addEventListener('keydown', (e) => {
  const tabs = [...tablist.querySelectorAll('[role="tab"]')];
  const currentIndex = tabs.indexOf(document.activeElement);

  let newIndex;
  switch (e.key) {
    case 'ArrowRight':
      newIndex = (currentIndex + 1) % tabs.length;
      break;
    case 'ArrowLeft':
      newIndex = (currentIndex - 1 + tabs.length) % tabs.length;
      break;
    case 'Home':
      newIndex = 0;
      break;
    case 'End':
      newIndex = tabs.length - 1;
      break;
    default:
      return;
  }

  tabs[newIndex].focus();
  tabs[newIndex].click();
  e.preventDefault();
});

Enough Time (2.2)

Users must have enough time to read and use content.

<!-- SC 2.2.1 Timing Adjustable (Level A) -->
<!-- If a time limit exists, users must be able to extend it -->

<div role="alert" id="session-warning" hidden>
  <p>Your session will expire in <span id="countdown">60</span> seconds.</p>
  <button onclick="extendSession()">Extend session by 15 minutes</button>
</div>

Help users find content and determine where they are.

<!-- SC 2.4.1 Bypass Blocks (Level A) -->
<a href="#main-content" class="skip-link">Skip to main content</a>

<!-- SC 2.4.2 Page Titled (Level A) -->
<title>Lesson 2: WCAG Guidelines - Accessibility Testing | Sabaoon Academy</title>

<!-- SC 2.4.6 Headings and Labels (Level AA) -->
<!-- Headings must be descriptive and in logical order -->
<h1>WCAG Guidelines</h1>
  <h2>Conformance Levels</h2>
  <h2>Key Success Criteria</h2>
    <h3>Text Alternatives</h3>
    <h3>Keyboard Accessible</h3>
  <h2>Testing Process</h2>

<!-- SC 2.4.7 Focus Visible (Level AA) -->
<style>
  /* Never remove focus outlines without providing an alternative */
  /* Bad */
  :focus { outline: none; }

  /* Good */
  :focus-visible {
    outline: 3px solid #4A90D9;
    outline-offset: 2px;
  }
</style>

WCAG Testing Checklist

Level A Checks (Must Have):
[  ] All images have appropriate alt text (1.1.1)
[  ] Content structure is conveyed through markup (1.3.1)
[  ] Color is not the only visual means of conveying info (1.4.1)
[  ] All functionality is keyboard accessible (2.1.1)
[  ] No keyboard traps exist (2.1.2)
[  ] Skip navigation link is provided (2.4.1)
[  ] Page has a descriptive title (2.4.2)
[  ] Link purpose is determinable from text (2.4.4)
[  ] Language of page is specified (3.1.1)
[  ] Input errors are identified and described (3.3.1)
[  ] HTML validates without significant errors (4.1.1)

Level AA Checks (Should Have):
[  ] Captions are provided for live audio (1.2.4)
[  ] Color contrast meets 4.5:1 for text (1.4.3)
[  ] Text can resize to 200% without loss (1.4.4)
[  ] Multiple ways to find pages (2.4.5)
[  ] Headings and labels are descriptive (2.4.6)
[  ] Focus is visible (2.4.7)
[  ] Consistent navigation (3.2.3)
[  ] Error suggestions are provided (3.3.3)

Key Takeaways

  • WCAG 2.2 Level AA is the standard target for most organizations
  • The POUR principles map to four WCAG categories (Perceivable, Operable, Understandable, Robust)
  • Each success criterion is testable with specific pass/fail conditions
  • Start with Level A compliance, then work toward AA
  • Use semantic HTML first -- it handles many criteria automatically

Next, you will learn how to test with screen readers, the most important assistive technology for accessibility testers.