WCAG 2.2 New Success Criteria: All 9 Explained With Examples

Every success criterion WCAG 2.2 added, in plain English: what it requires, what a failure looks like, how to test it, and which ones still need a person.

By Denis Omerovic ·

WCAG 2.2 shipped on 5 October 2023. It added 9 new success criteria on top of WCAG 2.1. Most of them are hard for an automated scanner to judge, because they depend on how a page behaves, where things sit on screen or what a person has to remember, so many tools leave them for manual review.

We just shipped automated checks for all 9 in AccessGuard. Several of them are partial by nature, and this post says which, so you know what still needs a person. Automated checks find many problems but cannot confirm conformance with WCAG.

If you are a developer, designer, or compliance owner, you can use this as a checklist regardless of which scanner you use. These are the things to audit on top of a WCAG 2.1 AA pass.

Why coverage was a problem

Most of the popular accessibility testing rules engines (including the one that ships inside Chrome DevTools) are very good at the deterministic stuff: missing alt text, bad heading order, low contrast, ARIA misuse. They are honest about what they do not check, and WCAG 2.2's new criteria sit almost entirely in the "do not check" bucket, because the new criteria require one of three things automated tools historically do not do well:

  1. Geometry. Real bounding boxes, real viewport math, real overlap detection.
  2. Behavioral analysis. What happens when the user actually focuses something, pastes into a field, or tries to drag.
  3. Context. Is this a login form? Is that element a chat widget? Is this the "help" link, or is it just a link that happens to say "help"?

Under the hood, AccessGuard already uses a headless Chromium via Ferrum to render pages with real CSS, real JavaScript, and real layout. We used that to actually solve the geometry and behavior problems instead of bolting on heuristics.

Here is what we now catch, and how.

The 9 new WCAG 2.2 criteria

2.4.11 Focus Not Obscured (Minimum) - Level AA

What it says, in plain English: When a keyboard user tabs to an element, that element must not be *entirely* hidden behind something else the author put on the page. The classic offender is a sticky header that covers the top 80 pixels of the viewport, so when a link near the top of the content scrolls into focus, the sticky header eats it.

Why it matters: Without this, screen reader and keyboard users can "focus" things they literally cannot see, and have no idea where they are on the page.

How we detect it: We grab the computed position, z-index, and bounding box of every element that has position: fixed or position: sticky. If it covers a significant horizontal slice of the viewport at the top or bottom edge and is taller than 40 pixels, we flag it as a potential obscurer. Narrow widgets like chat bubbles and back-to-top buttons are filtered out so we do not drown you in noise.

The fix is usually one line:

CSS
html {
  scroll-padding-top: 80px; /* match your sticky header height */
}

2.4.12 Focus Not Obscured (Enhanced) - Level AAA

Plain English: Same idea as 2.4.11, but stricter. *No part* of the focused element may be hidden, not just "not entirely hidden." If your sticky header clips even the top two pixels of a focused button's outline, you fail Enhanced.

How we detect it: We emit it alongside 2.4.11 as a separate Level AAA notice so you can see both signals without duplicating the scan.

2.4.13 Focus Appearance - Level AAA

Plain English: When something receives focus, the focus indicator must be big enough to actually see. The spec puts real numbers on this: the focus ring has to be at least 2 CSS pixels thick and have at least 3:1 contrast against the unfocused state.

Why it matters: A one-pixel light-grey outline on a white background technically exists but might as well not. Users cannot tell where focus is.

How we detect it: This is one of the trickiest. We had to teach our page fetcher to actually call element.focus({ preventScroll: true }) on every interactive element (up to a bounded sample per page for performance), read the computed :focus outline width, color, and background, then put the element back where it was. The checker then:

  1. Fails if there is no outline AND no box-shadow.
  2. Fails if the outline is thinner than 2 pixels.
  3. Runs the outline color through our existing contrast calculator against the element's background and fails if the ratio is below 3:1.

The thing most teams get wrong here is outline: none + a custom box-shadow that is too light. The shadow exists, but it is not 3:1, so it still fails. Our checker catches both.

The fix:

CSS
button:focus-visible {
  outline: 2px solid #005fcc; /* dark blue: ~7:1 on white */
  outline-offset: 2px;
}

2.5.7 Dragging Movements - Level AA

Plain English: If a user can do something by dragging (reorder a list, drag a card between columns, resize a panel), they must also be able to do that same thing with a single click or tap. Drag cannot be the only way.

Why it matters: Users with motor disabilities, tremors, people using switch controls, and anyone on a touch device without fine control, they cannot drag reliably or at all.

How we detect it: We look for the HTML5 draggable="true" attribute, inline drag event handlers (ondragstart, ondrag, etc.), touch-action: none on interactive elements, and the DOM markers left by common drag libraries: jQuery UI (.ui-sortable, .ui-draggable), Sortable.js, react-beautiful-dnd (data-rbd-draggable-id), and dnd-kit. For each drag target, we walk the surrounding container looking for a non-drag alternative: buttons labeled "Move up"/"Move down"/"Reorder," a position select control, or an aria-keyshortcuts attribute documenting keyboard shortcuts. If nothing is there, we flag it.

Real talk: If you built a Trello clone and you have not added keyboard reorder, you are almost certainly failing this criterion. react-beautiful-dnd has keyboard support built in but you have to opt into surfacing the instructions. dnd-kit is similar.

2.5.8 Target Size (Minimum) - Level AA

Plain English: Interactive targets have to be at least 24 by 24 CSS pixels. There are five exceptions, and the spacing one is the one most people get wrong.

The exceptions, rapid-fire:

  • Inline: A link inside a sentence inherits its size from the line height. That is allowed.
  • Spacing: The criterion passes undersized targets that are "positioned so that if a 24 CSS pixel diameter circle is centered on the bounding box of each, the circles do not intersect another target or the circle for another undersized target" (W3C, Understanding 2.5.8). In practice: 24 pixels from center to center of the nearest target. This is how icon toolbars are allowed to exist. Read the wording once more, because this is the part people get wrong: an undersized target with no other target near it has no circle to intersect, so it passes.
  • Equivalent: The same function is available from another control on the same page that is big enough.
  • User agent control: A native checkbox you did not restyle is sized by the browser, not by you. Not your fault.
  • Essential: The target's size is legally required to be what it is. Rare.

How we detect it: We measure real bounding boxes from the browser, not CSS string widths. For undersized targets, we compute the center-to-center distance to every other interactive element on the page. If any neighbor is within 24 pixels center to center, the spacing exception fails and we flag it. One caveat worth knowing while you read a report: our checker currently also flags an undersized target that has no neighbor at all, which the spacing exception passes. That is a false positive on our side rather than a failure on yours, and it is on our list to fix. Inline links inside <p>, <li>, table cells, and other text containers are exempted structurally. Native input[type=checkbox], radio, range, and color are treated as user-agent controlled and skipped. Elements with data-target-size-exempt="true" are treated as essential.

This last one matters because it removes a whole category of false positives that used to drown real signal. A 16-pixel icon inside a 32-pixel padded button is not a failure. A 16-pixel icon *is* the button? Different story.

3.2.6 Consistent Help - Level A

Plain English: If your site has help mechanisms (a contact link, a phone number, a chat widget, a FAQ link), and those mechanisms appear on multiple pages, they have to appear in the same relative place on each page. You cannot put "Contact" in the header on one page and halfway down the body on another.

Why it matters: Users who need help are often the most vulnerable and the least patient with your UI quirks. Making them hunt for the contact link every time is a real barrier.

How we detect it: Scoped to a single page, we cannot verify "same relative order across pages," but we can detect the situations that make that order *impossible* to keep consistent. We look for help mechanisms (tel:, mailto:, visible "Help"/"Support"/"Contact" links, aria-labeled help buttons, chat widget launchers for Intercom, Crisp, Drift, Tawk, Zendesk, HubSpot) and check whether each one lives inside a persistent landmark: <header>, <footer>, <nav>, <aside>, or their ARIA equivalents (banner, contentinfo, navigation, complementary). Help links buried in mid-body article content are flagged as a notice.

The advice is simple: put your contact link in the footer, not mid-paragraph.

3.3.7 Redundant Entry - Level A

Plain English: If a user has already given you a piece of information in the same process, you cannot make them type it again. Either auto-populate it, or let them select it.

Why it matters: This one is about cognitive load and typing effort. It matters for everyone but it matters disproportionately for users with memory, attention, or motor disabilities.

How we detect it: This checker is opinionated and catches the three most common real-world violations:

  1. Duplicate field groups. We look for field name stems like billing_street and shipping_street in the same form. If neither has an autocomplete token and there is no "same as billing" checkbox, we flag it.
  1. Missing autocomplete on reusable fields. input[type=email], type=tel, and name-like fields without an autocomplete attribute defeat the browser's ability to auto-fill anything. We flag those at notice level.
  1. Double email entry. Two email inputs in the same form is the classic redundant-entry failure. If paste is blocked on the second one, it becomes impossible to complete without retyping. We flag it either way, and include "paste is blocked" in the error message if we detect it.

The fix is almost always autocomplete tokens:

HTML
<input name="billing-address" autocomplete="billing street-address">
<input name="shipping-address" autocomplete="shipping street-address">

3.3.8 Accessible Authentication (Minimum) - Level AA

Plain English: Logging in cannot require a cognitive test. If your auth flow asks the user to remember a password, solve a puzzle, or read distorted text, you have to provide an alternative or a way to help.

The big one: Relying on a remembered password is, technically, a cognitive function test. The way you comply is by allowing password managers to fill the password for the user. The way you break compliance is by blocking paste on the password field or setting autocomplete="off", both of which are still extremely common "security" anti-patterns that actively reduce security and fail WCAG AA.

How we detect it, specifically in auth forms:

  • Password fields with onpaste="return false" or oncopy / oncut restrictions: error, because it actively defeats password managers.
  • Password fields with autocomplete="off": error, same reason.
  • Password fields with no autocomplete attribute at all: warning, because many password managers still guess, but not reliably.
  • Username fields in auth forms with no autocomplete="username" or autocomplete="email": notice, because managers cannot link credentials to the right account.
  • Image-recognition CAPTCHAs, puzzle CAPTCHAs, and distorted-text CAPTCHAs in auth flows: error. These are the textbook cognitive function test.

We explicitly exempt Cloudflare Turnstile and hCaptcha's basic "I am human" checkbox, because neither requires any cognitive work. Turnstile is how we just wired up bot protection on our own forms last week, specifically because it is the one anti-bot mechanism that does not fail 3.3.8.

The fix for most login forms is tiny:

HTML
<input type="email" name="email" autocomplete="email">
<input type="password" name="password" autocomplete="current-password">

For signup or reset, swap current-password for new-password. That is it. No JavaScript, no CSS. A one-line change per field that, statistically, most sites still have not made.

3.3.9 Accessible Authentication (Enhanced) - Level AAA

Plain English: Same as 3.3.8, but even stricter. Object recognition (pick the traffic lights) and personal-content questions (what is your mother's maiden name) stop being acceptable as alternatives.

How we detect it: When we find a cognitive CAPTCHA in an auth flow, we emit 3.3.8 as an error AND 3.3.9 as an AAA-level warning on the same element. If you are chasing AAA, passkeys, magic links, and OAuth are the paths.

Why we bothered with AAA

You will notice we shipped detection for the AAA criteria (2.4.12, 2.4.13, 3.3.9) even though almost no regulatory regime enforces AAA. Here is why:

  1. Accessibility is not pass/fail. A site that clears AA and notices a few AAA problems is strictly better than one that only clears AA and ignores everything else. The AAA-level notices are quiet by default (they do not turn your score red), but they tell you what to fix next.
  1. Some regulated sectors actually do care. Government, healthcare, and education increasingly ask for AAA in specific contexts like authentication and focus visibility.
  1. Legal floors move. The European Accessibility Act has applied to products and services placed on the market since 28 June 2025 (European Commission), and the EU standard behind it now points at WCAG 2.2: see what changed in EN 301 549 V4.1.1. Being able to *see* AAA issues means you can make a risk call, not a guess.

What this means if you are already using AccessGuard

You do not need to do anything. All five new checkers are registered in the orchestrator and will run on your next scan. The stricter target size and focus obscuring logic will also run automatically. Your existing scan results will not change retroactively, but the next scan will surface any 2.2 issues that were previously being counted as "manual review."

If your score drops, that is not the scanner getting meaner. It is the scanner finally seeing things it always should have seen.

What this means if you are not

Two options.

Option 1: Start a free scan at /scan. No signup. It runs all 33 checkers and will flag WCAG 2.2 issues on whatever URL you give it.

Option 2: Use this post as a checklist and audit your own site by hand. Everything we described is detectable with 15 minutes of DevTools and a real keyboard. The three highest-impact things to check right now, in order:

  1. Your login form. Does autocomplete="current-password" exist? Does paste work? If no CAPTCHA, you probably already meet 3.3.8. If a CAPTCHA, is it Turnstile or hCaptcha checkbox, or the picture thing?
  2. Your help link. Is it in the footer on every page, in the same position? Good. Is it buried in an article body on one page and in the nav on another? Fix it.
  3. Any drag interaction. Can a keyboard user do the same thing?

That is three tiny changes that address four of the nine 2.2 criteria. The remaining five take more work, but honestly, none of them take more than an afternoon per feature.

What is next

This post only covers the WCAG 2.2 additions. We run checks for WCAG 2.1 A and AA as well, plus axe-core 4.11 under the hood for the industry standard baseline. No automated suite covers every criterion: whether alt text is meaningful, whether captions match the audio, whether the focus order makes sense in your flow, all of that still needs a person, and our reports say so. Our next focus is reducing false positives on the noisier existing checkers, starting with the isolated target case above, then contrast and ARIA.

If you want to see the checker source, everything we shipped is on GitHub under the MIT license. The five new checkers are:

  • DraggingMovementsChecker (2.5.7)
  • ConsistentHelpChecker (3.2.6)
  • RedundantEntryChecker (3.3.7)
  • AccessibleAuthenticationChecker (3.3.8 + 3.3.9)
  • FocusAppearanceChecker (2.4.13)

Plus rewrites of FocusChecker (2.4.11 + 2.4.12) and TargetSizeChecker (2.5.8).

Questions, corrections, or "your heuristic missed my site"? We would love to know.


Want to check your own site? Run a free accessibility scan - no signup, WCAG 2.2 AA checks in a real browser, takes about 30 seconds.

Check a client site for this

Audit any page against WCAG 2.2 AA for free and see every finding in about 30 seconds.

Run a free audit