On each web page, are sudden changes in brightness or flashing effects used correctly?

A person with epilepsy visits your site. A promotional banner flashes rapidly across the entire screen. Three seconds later, they are having a seizure. This is not hypothetical: the opening ceremony video of the London 2012 Olympic Games triggered seizures in viewers. Criterion 13.7 exists to prevent this.

The rule operates on two alternative thresholds. Flashing or strobing content must not exceed 3 occurrences per second. If it crosses this threshold, its cumulative surface area must be less than 21,824 pixels to remain compliant. A large surface flashing slowly passes. A small surface flashing fast also passes. A large surface flashing fast: immediate rejection.

Three flashes per second. This is the absolute limit.

These thresholds apply to three distinct vectors: HTML multimedia elements (<img> animated, <video>, <svg>, <canvas>, <embed>, <object>), JavaScript scripts that alternate colors or opacities, and CSS animations. For auditing, source code analysis is sufficient in the vast majority of cases. An animation-duration: 0.15s with two alternating states produces 6.6 flashes per second. For videos, the PEAT tool analyzes .avi files and automatically flags at-risk sequences.

3 tests to detect dangerous flashing or brightness effects

Frequency or surface of flashes in multimedia elements

  1. Locate on the page all <img> elements (animated GIFs), <video>, <svg>, <canvas>, <embed> and <object> that produce flashing or luminous strobe effects.
  2. For each, verify that at least one of the following two conditions is met:
    • The frequency is less than 3 flashes per second;
    • OR the visual surface area affected in the rendering is less than 21,824 pixels.
  3. If at least one condition is met for each identified element, the test is validated.

For GIFs: tools like Ezgif display the duration of each frame. Frequency = 1 ÷ frame duration (in seconds). For videos: convert to .avi and analyze with PEAT.

Frequency or surface of flashes produced by script

  1. Search the JavaScript code for functions that rapidly modify colors, opacities or backgrounds. Target in particular: setInterval, recursive setTimeout, requestAnimationFrame and direct manipulations of style.backgroundColor or style.opacity.
  2. For each identified effect, calculate the frequency from the time interval and verify that at least one condition is met:
    • The frequency is less than 3 luminous changes per second;
    • OR the surface area of the affected element is less than 21,824 pixels.
  3. If no script exceeds both thresholds simultaneously, the test is validated.

Frequency or surface of flashes produced by CSS animation

  1. Search in stylesheets for @keyframes rules that alternate values of background-color, color, opacity or filter between a light state and a dark state.
  2. For each identified animation, calculate the frequency: number of luminous transitions ÷ animation-duration in seconds. A @keyframes with two states over animation-duration: 0.2s produces 10 flashes/s. Then verify that at least one condition is met:
    • The frequency is less than 3 flashes per second;
    • OR the rendered surface area of the animated element is less than 21,824 pixels.
  3. If all CSS animations meet at least one condition, the test is validated.

Examples

❌ Non-compliant : CSS animation flashing too rapidly on a large surface

<style>
  @keyframes flash-danger {
    0%, 49% { background-color: #ffffff; }
    50%, 100% { background-color: #000000; }
  }
  .banniere-promo {
    width: 900px;
    height: 200px;
    /* surface: 180,000 px², well above 21,824 px² */
    animation: flash-danger 0.15s infinite;
    /* frequency: ~6.6 flashes/s, above 3/s */
  }
</style>
<div class="banniere-promo">Limited offer!</div>

The animation alternates black and white every 0.15 seconds, producing approximately 6.6 flashes per second. The surface far exceeds 21,824 pixels. Both thresholds are exceeded simultaneously. For a photosensitive person, this type of content can trigger an epileptic seizure.

✅ Compliant : Status indicator animation compliant through reduced surface area and low frequency

<style>
  @keyframes pulse-statut {
    0%, 49% { background-color: #2e7d32; }
    50%, 100% { background-color: #66bb6a; }
  }
  .indicateur-statut {
    width: 12px;
    height: 12px;
    /* surface: 144 px², well below 21,824 px² */
    animation: pulse-statut 0.5s infinite;
    /* frequency: 2 flashes/s, below 3/s */
    border-radius: 50%;
  }
</style>
<span
  class="indicateur-statut"
  role="img"
  aria-label="Server online"
></span>

Two conditions pass simultaneously: the frequency is 2 flashes per second (below the 3 threshold) and the surface is 144 pixels (well below 21,824 pixels). Only one would be needed. The alternation occurs between two similar shades of green, which further reduces the brightness amplitude of the effect.

Tips and pitfalls

⚠️ The two thresholds are alternative, not cumulative

The most frequent audit error: believing that content must meet both conditions simultaneously. No. It is sufficient that the frequency is less than 3/s OR that the surface area is less than 21,824 pixels. A fast flash on a tiny element passes. A slow flash on a large surface also passes. It is only if both thresholds are exceeded simultaneously that the criterion fails.

💡 Calculate CSS animation frequency in ten seconds

Locate animation-duration and count the number of luminous transitions in the @keyframes. Formula: frequency = transitions ÷ duration (in seconds). A @keyframes with two states over animation-duration: 0.4s gives 2 ÷ 0.4 = 5 flashes/s. If the element's surface area is less than 21,824 pixels, it is compliant despite the high frequency.

⚠️ Animated GIFs are subject to the same requirements as videos

A GIF inserted via <img> falls under test 13.7.1. Ezgif or FFmpeg allow you to inspect the duration of each frame. If frames last 80 ms and alternate between two high-contrast luminosities, you obtain 12.5 flashes/s. Also check the surface area of the <img> element in the final rendering: a 20×20 pixel GIF passes the surface threshold even at high frequency.

⚠️ 13.7 concerns seizure risk, 13.8 concerns distraction

Criterion 13.7 targets abrupt luminosity changes that can trigger seizures. Criterion 13.8 concerns moving or flashing content that is bothersome but not dangerous (scrolling animations, carousels, counters). A loading spinner that rotates falls under 13.8. A banner that alternates black and white at 4 Hz falls under 13.7. Both criteria can apply to the same element.

💡 PEAT only accepts .avi format

The PEAT tool (Photosensitive Epilepsy Analysis Tool), developed by Cambridge Research Systems, is the reference for analyzing videos. It only accepts .avi format. Convert your MP4, WebM or MOV sources with ffmpeg before analysis: ffmpeg -i video.mp4 video.avi. The tool generates a precise report with timestamps of non-compliant sequences.

Frequently asked questions

How do you measure whether a CSS animation exceeds 3 flashes per second for RGAA?

Formula: frequency = (number of transitions between light state and dark state in one cycle) ÷ (value of animation-duration in seconds). With animation-duration: 0.3s and two alternating states: 2 ÷ 0.3 = 6.6 flashes/s. Exceeded. If the surface area of the animated element is less than 21,824 pixels in the rendering, the criterion remains compliant despite the high frequency.

How do you apply RGAA criterion 13.7 to videos embedded via YouTube iframe?

Yes. The criterion applies to all content present on the page, whether self-hosted or embedded via <iframe>. You do not control the editing of the YouTube video, but you are responsible for what you embed. If the video contains at-risk sequences, display a visible warning before playback and offer an alternative.

What is the difference between prefers-reduced-motion and RGAA criterion 13.7 requirements?

None. The prefers-reduced-motion media query is a good practice, but it does not replace compliance with criterion 13.7. This criterion is unconditional: no content can exceed flash thresholds, whether or not the user has enabled this system preference. prefers-reduced-motion is more relevant for criteria 13.8 and best practices for visual comfort.

What screen size does the 21,824 pixel threshold in RGAA 13.7 correspond to?

Approximately a square of 148×148 pixels, or a rectangle of 300×73 pixels. This threshold represents 25% of the central field of vision at 10 degrees for a standard screen viewed at normal distance (WCAG G176 technique). A small animated badge or status indicator rarely exceeds this threshold. A full-width hero banner or auto-playing video almost systematically exceeds it.

How do you audit JavaScript that dynamically modifies colors according to criterion 13.7?

Look for calls to setInterval, recursive setTimeout and requestAnimationFrame that modify style.backgroundColor, style.opacity or add and remove CSS classes. Calculate the frequency from the time interval. If the script is minified or obfuscated, slow down the CPU in DevTools (Performance tab, CPU throttling to 4×) and visually count the luminous transitions over one second.

References