Is each time-based and non-time-based medium compatible with assistive technologies (except in special cases)?

A screen reader user lands on a page with a custom video player. They press Tab. Focus lands on a 'Play' button made of a <div>. The screen reader announces: nothing. The control exists visually — it is invisible to assistive technologies.

Criterion 4.13 requires that every multimedia player (video, audio, non-timed animation) expose its interface components via an accessibility API. Name, role, value, and state of each control must be programmatically readable. The Play button must have a button role and an accessible name. The progress bar must expose its current value. Dynamic state changes (switching from 'Play' to 'Pause') must be announced in real time.

Two paths are available to you. The simplest: use the native HTML element <video controls> or <audio controls>, whose controls are natively exposed by browsers. No ARIA to manage, no state to synchronize. The second: build a custom player with ARIA — role="button", aria-label, aria-pressed, aria-valuenow on volume and progress sliders. This requires more work, with greater risk of error.

If the player is not directly compatible, the criterion accepts an accessible alternative placed nearby: a replacement player, accessible via an adjacent link or button, or a mechanism allowing substitution of the original player.

2 tests to ensure compatibility of media with assistive technologies

Compatibility of media with assistive technologies

  1. List all media on the page: videos, audio players, animations, non-timed multimedia content (<video>, <audio>, <object>, custom JavaScript players).
  2. For each player, inspect each interface control (play, pause, volume, fullscreen, captions, progress bar).
  3. Verify that each control exposes via the accessibility API:
    • Its accessible name (readable by a screen reader);
    • Its role (button, slider, checkbox, etc.);
    • Its current value and state (e.g., volume at 80%, playback ongoing);
    • Dynamic state changes (switching from 'Play' to 'Pause').
  4. If the player itself does not expose this information, verify that an accessible alternative offering the same functionality is provided.
  5. If at least one of the two conditions is met for each media: test passes.

Accessibility of compatible alternative to media

This test concerns only media that offer an accessible alternative (replacement player, alternative version).

  1. For each affected media, verify that the alternative is reachable according to one of these three methods:
    • The alternative is placed directly next to the media on the page;
    • An adjacent link or button provides access to it;
    • A mechanism allows substituting the original player with its accessible alternative.
  2. If this is the case for each media with an alternative: test passes.

Examples

❌ Non-compliant : Custom player without ARIA exposure

<div class="video-player">
  <div class="play-btn" onclick="togglePlay()">&#9654;</div>
  <div class="progress-bar">
    <div class="progress-fill" style="width: 30%"></div>
  </div>
  <div class="volume-ctrl" onclick="toggleMute()">&#128266;</div>
</div>

None of this player's controls are exposed via the accessibility API. The screen reader sees anonymous <div> elements, without role, without name, without state. The user cannot trigger playback with the keyboard, know the sound state, or track progress. The player is functionally visible and non-existent for assistive technologies.

✅ Compliant : Custom player with complete ARIA

<div class="video-player" role="region" aria-label="Video player">
  <button type="button" id="btn-play" aria-label="Play" aria-pressed="false"
          onclick="togglePlay(this)">
    <svg aria-hidden="true" focusable="false"><use href="#icon-play"/></svg>
  </button>
  <div role="slider"
       aria-label="Video progress"
       aria-valuemin="0"
       aria-valuemax="100"
       aria-valuenow="30"
       aria-valuetext="30 percent"
       tabindex="0">
  </div>
  <button type="button" aria-label="Mute" aria-pressed="false"
          onclick="toggleMute(this)">
    <svg aria-hidden="true" focusable="false"><use href="#icon-volume"/></svg>
  </button>
</div>

Each control exposes its name (aria-label), role (button, slider), and state (aria-pressed, aria-valuenow). When the user triggers playback, the JavaScript must update aria-pressed="true" and change aria-label to 'Pause' to reflect the new state. The screen reader announces each action and each change.

Tips and pitfalls

⚠️ Update the visual DOM without synchronizing ARIA

A player that changes its button visually from 'Play' to 'Pause' without updating aria-label or aria-pressed creates a silent desynchronization. The user hears 'Play' while the video is running. This is the most common error in homemade players, and it is completely invisible to visual auditing.

💡 Native <video controls>: the most reliable path

Browser native controls are exposed via the operating system's accessibility API without any line of ARIA. Less graphical customization, zero risk of state oversight. If your design allows it, this is the best choice. Still verify with a real screen reader: some older browser/screen reader combinations have occasional gaps.

⚠️ Purely decorative media: criterion not applicable

A background video loop on a page that conveys no information is not subject to criterion 4.13. But be careful not to abuse this exception: an 'ambient' video showing people using a product implicitly conveys a message. If removing the media would cause information loss to the user, it is not decorative.

⚠️ Embedded players (YouTube, Vimeo) — verification required

Players integrated via <iframe> have their own accessibility levels. The embedded YouTube player generally exposes its controls, but certain custom configurations (parameter controls=0) hide them. Verify with a real screen reader and provide an adjacent link to the native video page if the embedded player does not pass the test.

⚠️ An alternative present is not enough — it must also be accessible

Test 4.13.2 verifies the presence of an alternative and its navigability. But if this alternative is itself a non-compliant player, you have gained nothing. The alternative must be compatible with assistive technologies, not just present in the DOM.

Frequently asked questions

Under what conditions does a native <video controls> HTML satisfy RGAA criterion 4.13?

Yes, in the vast majority of cases. Native controls are exposed via the operating system's accessibility API without additional configuration. Still test with NVDA + Firefox and VoiceOver + Safari, as some older combinations have gaps. The controls attribute is essential: a <video> without it displays no controls and cannot be operated.

How do I concretely audit media compatibility according to RGAA criterion 4.13?

Navigate the player with the keyboard: each control must be reachable by Tab and activable by Enter or Space. Then activate a screen reader (NVDA, VoiceOver, JAWS) and browse the controls: it must announce the name, role, and state of each element, and render dynamic changes. Supplement with Chrome DevTools Accessibility panel to inspect the accessibility tree of each component.

How do I compensate for an inaccessible third-party video player to satisfy RGAA criterion 4.13?

Under conditions, yes. The link must be adjacent to the failing player, clearly identified, and point to a page where the content is accessible. This is not a universal solution: redirecting the user outside the page is not always acceptable depending on context. If the embedded player is central to a user journey, a local alternative is preferable.

When does RGAA criterion 4.13 apply to CSS or animated SVG animations?

Pure CSS animations without interactive control are not media in the sense of criterion 4.13. However, if an animation embeds user controls (pause button, slider), these controls fall within scope: they must expose name, role, and state via the accessibility API. Criterion 13.8 on animation control completes this framework.

References