Search topics
Flashing banners and videos that can trigger seizures
A flash-sale banner swaps black and yellow five times a second across the full width of the page: fast, bright and large enough to set off a seizure in people with photosensitive epilepsy.
animation: strobe 0.2s steps(1) infinite; The problem
People with photosensitive epilepsy can have a seizure from a few seconds of a large, bright banner flashing five times a second, before they have time to look away.
A clothing shop runs a one-day sale. Across the top of the home page, a full-width banner reads "Flash sale: 50% off everything until midnight", and to make the words "flash sale" literal, the banner flashes: black with yellow text, then yellow with black text, ten times a second, so it goes dark and light again five times a second. It starts as the page loads and keeps going for as long as the page is open. The same failure turns up as a "glitch" effect on a hero heading, a game or product trailer with strobe lighting that plays by itself, a "lightning" GIF in a promotion, or an error state that flashes the whole screen red.
Success criterion 2.3.1 Three Flashes or Below Threshold allows a page to flash more than three times in any one second only if the flash is below both the general flash and the red flash thresholds. A general flash is a pair of opposing changes in relative luminance of 10% or more of white, where the darker state is below 0.80; a red flash is a pair of changes to and from a saturated red. The threshold is passed when the flashing covers more than a quarter of a 10-degree visual field, which W3C estimates as a 341 × 256 CSS pixel area. The banner fails on every count. Black is close to 0 in relative luminance and the yellow is about 0.68, so every swap is a general flash; it flashes five times a second; and a banner 110 pixels tall across the page covers about 43% of that area. 2.3.1 is one of the few criteria that applies to everything on the page, even content a conforming alternative version exists for: W3C lists it under conformance requirement 5, non-interference, since the flash reaches people before they could ever choose another version.
Around 3% of people with epilepsy are photosensitive, most of them developing it between the ages of 7 and 19, and someone who has never had a seizure has no reason to know they are. A shop's home page is also where people browse on a phone held close to the face, which makes the banner cover even more of what they see.
2 of 10 groups affected
- No vision (not affected)
- Low vision (not affected)
- Colour vision (not affected)
- No hearing (not affected)
- Hard of hearing (not affected)
- No speech (not affected)
- Motor (not affected)
- Reach, strength (not affected)
- Cognitive (affected)
- Seizures (affected)
- Photosensitive seizures A bright banner swapping black and yellow five times a second, across much of what they see, is in the range of flashing most likely to set off a seizure, and it starts as the page loads, before anyone can look away or find a control.
- Limited language, cognitive and learning abilities A strobe across the top of the page keeps pulling the eye back to it, so people with attention difficulties can't settle on the products and prices under it.
The audit now measures flashing it can read from the page: it steps every CSS and Web Animations API animation through its first seconds, watches for scripts that swap a class on a timer, reads the colours each time, counts flashes in any one second, and measures the area against the 341 × 256 field. It reports the banner above as a finding with its rate, colours and size. It can't see inside video, animated GIFs, Lottie files or canvas, and it can't know the brightness of a banner blinking over a photo; those need a flash analysis tool. axe and linters have no flash rule at all. AI tools usually answer a flashing banner by wrapping it in a reduced-motion query or adding a Pause button, and neither passes. "Flash sale" and "glitch text" snippets online often use steps() timing a tenth of a second long, so AI-written CSS brings the failure with it.
Try it
See how often the sale banner flashes in one second, and how much of the view it covers.
This page never plays flashing faster than three times a second, so the broken banner strobes at a fifth of its speed, and the strip under it shows its real second, frame by frame. The dashed box is 341 × 256 pixels, W3C’s estimate of a 10-degree field of view: a fast flash may cover a quarter of it. "Stop demo" is the Learn page’s own button, not the shop’s.
Broken Can you fix this?
Flash sale: 50% off everything until midnight
- Wool coat $90
- Linen shirt $34
- Canvas tote $22
The box is 341 × 256 pixels, W3C’s estimate of what the eye takes in at once. A flash this fast may fill a quarter of it; the hatched part is the banner’s share.
The fix
Stop the flashing, slow it to one flash a second that ends after three, or keep the strobe to a small badge.
- 1Flash no more than three times in any one second, or keep the flash under a quarter of a 10-degree field.
- 2A warning, a Pause button or the reduced-motion query is never the fix.
- 3Check video and animated images with a flash analysis tool before they go live.
<div class="flash-sale"> <p>Flash sale: 50% off everything until midnight</p></div>A still banner
<div class="flash-sale"> <p>Flash sale: 50% off everything until midnight</p></div>Why this fix: Flash no more than three times a second
steps(1) jumps straight from black to yellow and back with no fade, every 0.1 seconds: five flashes a second, from dark to bright, over a large part of the screen, without end.
Nothing changes, so nothing flashes, and there is nothing to measure. The banner keeps the sale's colours, black on bright yellow with a heavy black edge above and below, and it still stands out as the brightest thing on the page. It also passes 2.3.2 and 2.2.2 with nothing to keep in check.
All three pass 2.3.1. The still banner needs no measuring and passes every flash and motion criterion; what it gives up is the flash itself, so the design has to earn attention with colour and size. One flash a second keeps a blink as the page opens, at a rate below which seizures are uncommon, by changing two values; choose it when the brief asks for movement. The small badge keeps a fast strobe, but it passes only while it stays small and alone, and fails 2.3.2; choose it only when a fast flash is part of a brand you can't change, and plan to slow it when you can.
Count flashes as pairs. A swap to light and back is one flash, so an animation that changes once each way per cycle flashes once per animation-duration. With animation-direction: alternate, each cycle is only half a flash, so 0.2s alternate flashes 2.5 times a second. Keep every cycle at one second or longer and the count never needs care.
Some changes look like fixes and are not. Each leaves the flash in place for someone.
- A seizure warning before the page or the video: by the time it is read, the flash is on screen, and someone who has never had a seizure doesn't know to heed it.
- A Pause or Stop button: W3C notes that turning the flash off is not an option, because a seizure can come faster than most people could turn it off.
- The reduced-motion query alone: most people with photosensitive epilepsy have never set it. Write motion inside
no-preferenceas well, never instead of a safe rate.
A change between two light colours is not a general flash when the darker of them has a relative luminance of 0.80 or more, such as a pale yellow flickering to a paler one. It passes on paper, but the next brand colour can break it, and a change to or from a saturated red counts as a red flash even with no change in brightness. Red is counted on its own because red flashing is especially likely to set off seizures: the red and blue flashing in a 1997 anime episode sent hundreds of viewers in Japan to hospital. Treat a pale flicker as the small badge is treated, and confirm it with a tool.
Video, animated GIFs, Lottie files and canvas animations hold the flash in their frames, so CSS can't fix them. Run each through a flash analysis tool at the size the page shows it, such as PEAT, a free Windows tool from the Trace Center, or IRIS, an open-source library from EA that checks video for luminance flashes, red flashes and patterns. Then fix the edit: cut or slow the strobe, darken it, or shrink it in the frame. A third-party ad or embed counts too, because 2.3.1 applies to everything on the page.
Flashing is not the only movement on a sale page. A banner that pulses or glows without end, a ticker and a countdown each have their own guides: pulsing buttons, glowing badges and animations that never stop and tickers, carousels and animations that can't be paused. A small badge or dot that blinks fast is the subject of badges and icons that blink more than three times a second.
Fixing this with an AI coding assistant? Get this guide as Markdown
Verify the fix
5 checks, no mouse.
Test with: Flash analysis, Reduced motion, Zoom
Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the design, a campaign banner, a video or the animation library changes.
Limits
This is a starting pattern, not a guarantee for every application, and not medical advice. The thresholds lower the risk of a seizure but don't remove it: some people react below three flashes a second, and to still patterns of stripes or checks that 2.3.1 doesn't cover. The audit measures flashes it can read from the page, not video, animated images or canvas, and it doesn't add up small flashes that sit side by side. A flash analysis tool and a person still need to check what it can't see.
This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.
References
- WCAG Understanding: three-flashes-or-below-threshold (opens in a new tab)
- w3.org: WCAG22 (opens in a new tab)
- WCAG Technique G19 (opens in a new tab)
- WCAG Technique G176 (opens in a new tab)
- WCAG Technique G15 (opens in a new tab)
- trace.umd.edu: peat (opens in a new tab)
- github.com: IRIS (opens in a new tab)
- epilepsysociety.org.uk: photosensitive-epilepsy (opens in a new tab)
Keep this fixed as your code changes.
Turn guides like this into rules your coding agents and CI follow, then have the result retested with a keyboard and screen readers.