Skip to main content

What WCAG requirements apply to product tours?

Map 16 WCAG 2.1 AA criteria to product tour components. Focus traps, screen reader announcements, contrast ratios, and keyboard navigation with code.

DomiDex
DomiDexCreator of Tour Kit
April 11, 202610 min read
Share
What WCAG requirements apply to product tours?

What WCAG requirements apply to product tours?

Product tours are modal dialogs, tooltips, and overlays chained into a sequence. Every component in that chain carries specific WCAG 2.1 AA obligations, and most tour libraries fail at least three of them. With 3,188 ADA website lawsuits filed in 2024 alone (EcomBack Annual Report) and the DOJ's April 24, 2026 deadline for WCAG 2.1 AA compliance on government sites, accessibility isn't optional.

This article maps every relevant WCAG success criterion to specific product tour components, shows the exact markup and behavior required, and flags the mistakes most libraries make.

npm install @tourkit/core @tourkit/react

Short answer

Product tours must meet at least 16 WCAG 2.1 AA success criteria. The most critical: tour steps need role="dialog" with aria-modal="true" (SC 4.1.2), focus must move into each step and trap within it (SC 2.4.3, 2.1.2), Escape must dismiss the current step (SC 1.4.13), and step transitions must announce to screen readers via focus movement or aria-live regions (SC 4.1.3). Tour Kit implements all 16 criteria in its headless components, giving you compliant defaults without prescribing your UI.

The 16 WCAG criteria that apply to product tours

Every product tour is a sequence of interactive overlays. Each overlay triggers a specific set of WCAG success criteria. We mapped all 16 that apply directly to tour implementations:

CriterionLevelWhat it means for your tour
1.1.1 Non-text ContentAImages inside tour steps need alt text
1.3.1 Info and RelationshipsATour step containers need semantic markup, not just visual styling
1.4.3 Contrast (Minimum)AATour popover text requires 4.5:1 contrast ratio against its background
1.4.4 Resize TextAATour content must remain functional at 200% browser zoom
1.4.11 Non-text ContrastAAClose button icons and progress dots need 3:1 contrast
1.4.12 Text SpacingAATour text must not break when users override line-height and letter-spacing
1.4.13 Content on Hover/FocusAATooltip-style steps must be dismissible (Escape), hoverable, and persistent
2.1.1 KeyboardANext, Back, Skip, and Close buttons all keyboard-operable
2.1.2 No Keyboard TrapAFocus trapped inside step, but Escape always exits
2.4.3 Focus OrderAFocus moves into each step on open, returns to trigger on close
2.4.7 Focus VisibleAAActive tour control shows a visible focus indicator
2.5.3 Label in NameAButton's accessible name must contain its visible text
2.5.8 Target SizeAATour controls minimum 24×24px (WCAG 2.2 — enforced by EU from June 2025)
3.3.1 Error IdentificationAIf tour includes input fields, errors must be identified accessibly
4.1.2 Name, Role, ValueAStep container needs role="dialog", aria-labelledby, aria-modal="true"
4.1.3 Status MessagesAAStep transitions must announce to screen readers

Source: W3C WCAG 2.1 Specification, with tour-specific interpretations based on Understanding SC 1.4.13.

94.8% of home pages had detected WCAG failures in 2025 (WebAIM Million Report), averaging 51 errors per page. Product tours add a new layer of interactive content on top of that baseline — and most tour libraries don't address the criteria above at all.

Focus management: the requirement most tours fail

Focus management is the number one accessibility failure in product tour implementations. When a step opens, keyboard focus must move into it. When it closes, focus returns to a logical location.

Here's the required flow for WCAG 2.4.3 (Focus Order) and 2.1.2 (No Keyboard Trap):

  1. User activates the tour trigger (button click, keyboard Enter)
  2. First step opens — focus moves to the step container or its first focusable element
  3. Tab cycles only within the step (focus trap per 2.1.2)
  4. Escape always dismisses the step (required by 1.4.13)
  5. On close, focus returns to the element that triggered the tour
  6. On step advance, focus moves to the new step container

The tricky case: what happens when the user presses Escape on step 4 of 7? Focus should return to the original trigger element, not the highlighted element from step 4. Most libraries get this wrong. They either leave focus stranded on the overlay backdrop or jump it to document.body.

// src/components/AccessibleTourStep.tsx
import { useEffect, useRef } from 'react';

function AccessibleTourStep({
  title,
  body,
  onNext,
  onBack,
  onClose,
  stepNumber,
  totalSteps,
}: {
  title: string;
  body: string;
  onNext: () => void;
  onBack: () => void;
  onClose: () => void;
  stepNumber: number;
  totalSteps: number;
}) {
  const stepRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    // Move focus into step when it opens (WCAG 2.4.3)
    stepRef.current?.focus();
  }, [stepNumber]);

  return (
    <div
      ref={stepRef}
      role="dialog"
      aria-modal="true"
      aria-labelledby="tour-step-title"
      aria-describedby="tour-step-body"
      tabIndex={-1}
      onKeyDown={(e) => {
        // Escape always dismisses (WCAG 1.4.13)
        if (e.key === 'Escape') onClose();
      }}
    >
      <h2 id="tour-step-title">{title}</h2>
      <p id="tour-step-body">{body}</p>
      <p aria-live="polite">
        Step {stepNumber} of {totalSteps}
      </p>
      <button onClick={onBack} disabled={stepNumber === 1}>
        Back
      </button>
      <button onClick={stepNumber === totalSteps ? onClose : onNext}>
        {stepNumber === totalSteps ? 'Finish' : 'Next'}
      </button>
      <button onClick={onClose} aria-label="Close tour">
        ×
      </button>
    </div>
  );
}

This covers four criteria in one component: role="dialog" with aria-modal (4.1.2), focus on mount (2.4.3), Escape to dismiss (1.4.13), and live region for step progress (4.1.3).

Visual requirements: contrast, sizing, and motion

Tour popovers frequently fail three visual WCAG criteria that are straightforward to fix but rarely checked.

Contrast ratios (SC 1.4.3 and 1.4.11): Tour step text against its background needs 4.5:1 for normal text, 3:1 for large text (18px+ or 14px+ bold). UI components like close buttons and progress indicators need 3:1 against adjacent colors. White text on a light blue popover (a common library default) almost never passes.

Target sizes (SC 2.5.8, WCAG 2.2): Tour navigation buttons must be at least 24×24 CSS pixels. The recommended size is 44×44px (Apple Human Interface Guidelines). Icon-only "x" close buttons are the worst offender, often 16x16px or smaller. The European Accessibility Act (enforceable since June 2025) references WCAG 2.2, making this criterion mandatory for any product serving EU users.

Motion (SC 2.3.3 and general best practice): Tour entry animations and step-change effects must respect prefers-reduced-motion. This is AAA level in WCAG 2.1, but it's a baseline expectation in 2026. The European Accessibility Act's reference to WCAG 2.2 makes motion reduction effectively mandatory for EU compliance.

/* Respect user motion preferences */
@media (prefers-reduced-motion: reduce) {
  .tour-step {
    animation: none;
    transition: none;
  }

  .tour-spotlight {
    transition: none;
  }
}

We tested multiple product tour libraries with Chrome DevTools' accessibility audit. Libraries that inject their own styled components (rather than letting you render your own) consistently failed contrast checks because their default themes weren't designed with 4.5:1 ratios in mind.

Screen reader announcements for step transitions

When a product tour moves from one step to another, screen reader users need to know. Silence during a step transition means the user doesn't know the tour advanced, repeated the same content, or ended.

Two valid approaches exist:

Approach 1: Focus movement. Move focus to the new step's dialog container on each transition. The screen reader reads the new content because focus landed there. This is the simpler approach and works with all screen readers.

Approach 2: Live regions. Keep an aria-live="polite" region that announces "Step 3 of 5: [step title]" on each transition. This works when focus shouldn't move (for example, when the user is mid-typing in a form field during a contextual tour).

Tour Kit uses approach 1 by default (focus moves to each new step container) and falls back to approach 2 for non-modal hint-style tours where moving focus would interrupt the user's workflow.

One thing we learned: aria-live="assertive" is wrong here. Assertive announcements interrupt whatever the screen reader is currently speaking, which creates a jarring experience during multi-step tours. Polite regions wait for the current utterance to finish.

How tour libraries compare on WCAG compliance

Not all tour libraries handle accessibility the same way. We tested five popular options against the 16 WCAG criteria above. The results show a clear divide between libraries that inject pre-styled components and those that let you render your own.

WCAG requirementTour KitReact JoyrideShepherd.jsDriver.js
role="dialog" + aria-modal (4.1.2)Yes (default)Partial (no aria-modal)YesNo
Focus moves to step on open (2.4.3)YesNoYesNo
Focus trap within step (2.1.2)YesNoPartialNo
Escape dismisses step (1.4.13)YesYesYesYes
Focus returns to trigger on close (2.4.3)YesNoNoNo
Screen reader step announcements (4.1.3)Yes (aria-live)NoNoNo
prefers-reduced-motion (2.3.3)YesNoNoNo
Contrast controllable by user (1.4.3)Yes (headless)Limited (themed)Limited (themed)Limited (themed)

The pattern is clear: libraries that inject their own styled components tend to handle Escape key dismissal but miss focus management, screen reader announcements, and motion preferences. Headless libraries leave UI rendering to you, so your existing accessible components handle contrast and sizing naturally.

Decision framework: when each approach fits

Choosing the right accessibility approach for your product tours depends on your team, your compliance requirements, and your existing component infrastructure.

  • If you have an existing accessible design system (shadcn/ui, Radix, your own components), use a headless tour library. Your components already handle ARIA, focus, and contrast. A headless library like Tour Kit plugs into them instead of replacing them.
  • If you need WCAG 2.2 AA for EU compliance (European Accessibility Act, enforceable since June 2025), audit your tour library against SC 2.5.8 (24x24px target sizes) and SC 2.3.3 (motion reduction). Most libraries fail both.
  • If you're building for US government users, the April 24, 2026 DOJ deadline requires WCAG 2.1 AA. Every tour step is a modal dialog under the spec, so the full dialog accessibility pattern applies.
  • If you're shipping fast and will audit later, at minimum implement role="dialog", aria-modal="true", Escape to close, and focus-on-open. These four attributes prevent the worst screen reader failures.

The overlay trap: why widgets don't fix tour compliance

In 2024, 722 of 3,188 ADA lawsuits (22.65%) targeted websites that already had an accessibility overlay or widget installed (EcomBack 2024 Report). Having a widget didn't prevent the lawsuit. In some cases it made things worse.

72% of users with disabilities rated overlay widgets as ineffective. Only 2.4% rated them "very effective" (Overlay Fact Sheet, signed by 550+ accessibility professionals).

One screen reader user described the problem directly: "any site which has deployed an overlay in the past year and a half has been less useable for both my wife and me, both blind."

This matters for product tours because many tour libraries use the same overlay injection pattern. They append styled DOM nodes to the page and assume the result is accessible. It isn't. A tour built on overlay injection without proper ARIA semantics and focus management creates the same problems that accessibility overlays do.

How Tour Kit handles WCAG compliance

Tour Kit takes the headless approach to accessibility. Instead of shipping pre-styled tooltips with questionable ARIA markup, it provides hooks and logic. You render the UI with your own components.

What this means in practice:

  • useTour() manages focus automatically, moving focus to each step on transition and returning to the trigger on close (SC 2.4.3)
  • Step containers include role="dialog" with aria-modal and aria-labelledby by default (SC 4.1.2)
  • Built-in Escape key handling on every step (SC 1.4.13)
  • Focus trap implementation that cycles Tab within the active step (SC 2.1.2)
  • aria-live region announces step transitions to screen readers (SC 4.1.3)
  • prefers-reduced-motion respected in all default animations

Since you bring your own UI components, contrast ratios and target sizes match your existing design system rather than fighting a library's defaults.

Tour Kit doesn't have a visual builder, and it requires React 18+. If you need a drag-and-drop tour editor or support for older frameworks, it won't fit. But if your team writes React and cares about shipping accessible UIs, the headless approach means fewer WCAG violations to fix later.

Explore the full accessibility API at usertourkit.com.

FAQ

Which WCAG level do product tours need to meet?

Product tours should meet WCAG 2.1 Level AA at minimum. The DOJ's April 24, 2026 deadline mandates WCAG 2.1 AA for US government sites. The European Accessibility Act (enforceable since June 2025) references WCAG 2.2 AA via EN 301 549. Enterprise procurement increasingly requires AA compliance for all web applications, including product tours.

Do product tour overlays need focus traps?

Yes. WCAG 2.1.2 (No Keyboard Trap) and 2.4.3 (Focus Order) require that modal content, including product tour steps, trap keyboard focus within the active step. Tab cycles through the step's interactive elements. Escape must always dismiss. Tour Kit's useTour() hook handles both automatically.

Can accessibility overlay widgets make my tours compliant?

No. In 2024, 722 ADA lawsuits targeted sites that already had accessibility overlays installed. 72% of users with disabilities rated these widgets as ineffective (Overlay Fact Sheet). Overlay widgets cannot retroactively add proper focus management, ARIA roles, or keyboard navigation to tour components. These must be built into the tour implementation itself.

What contrast ratio do tour tooltips need?

Tour tooltip text needs a 4.5:1 contrast ratio against its background (WCAG SC 1.4.3). Non-text UI elements like close buttons and progress dots need 3:1 (SC 1.4.11). White text on light backgrounds, a common default in tour libraries, rarely meets the 4.5:1 threshold.

How should screen readers announce tour step changes?

Screen readers should be notified of step transitions either through focus movement (moving focus to the new step's dialog container) or through an aria-live="polite" region that announces the new step content. Tour Kit uses focus movement by default and provides an aria-live fallback for non-modal hint tours where focus movement would disrupt user input.

Ready to try userTourKit?

$ pnpm add @tour-kit/react