Skip to main content

Notes

Flashing Content and WCAG SC 2.3.1: Why "Flash Sale" Banners and Autoplay Video Need a Safety Check

Quietramp ·

Flashing Content and WCAG SC 2.3.1: Why “Flash Sale” Banners and Autoplay Video Need a Safety Check

Quick answer: WCAG SC 2.3.1 Three Flashes or Below Threshold (Level A) says a web page must not contain anything that flashes more than three times in any one-second period, unless the flash is below a defined brightness/size threshold. It exists to prevent seizures in people with photosensitive epilepsy, and unlike almost every other WCAG criterion, it applies to all content on a page — including things unrelated to any other success criterion — because a large enough flash can make the whole page unusable regardless of what else is accessible. On e-commerce sites, the real-world triggers are mundane: an animated GIF promo banner, an autoplaying product-teaser video with fast strobe-style cuts, or a hand-rolled CSS “pulse” animation on a low-stock badge or countdown timer.

This article covers technical accessibility practice, not legal advice — it explains what a WCAG success criterion requires and how to check for it, not whether a specific site carries legal risk.

What SC 2.3.1 actually requires

The criterion’s own text: “Web pages do not contain anything that flashes more than three times in any one second period, or the flash is below the general flash and red flash thresholds.” The Understanding doc states the intent plainly: “to allow users to access the full content of a site without inducing seizures due to photosensitivity.” People are more sensitive to red flashing specifically, which is why the criterion defines a separate, stricter threshold just for it.

One detail sets this criterion apart from most others: because uncontrolled flashing “can interfere with a user’s ability to use the whole page,” it applies to all content on the page, “whether it is used to meet other success criteria or not.” A flashing background pattern that isn’t load-bearing for any other requirement still has to pass this one.

Content passes if either of these is true within any one-second period: there are no more than three general (or three red) flashes, or the combined flashing area at any one moment takes up no more than about 25% of a 10-degree visual field at typical viewing distance — small enough that even a fast flash rate poses much less risk. A “general flash” itself is a defined term: “a pair of opposing changes in relative luminance of 10% or more of the maximum relative luminance… where the relative luminance of the darker image is below 0.80” — in plain terms, a light-to-dark brightness swing big enough to matter, repeated too fast.

Flashing vs. blinking

The Understanding doc draws a deliberate line between two problems that can look similar: “‘Blinking’ refers to content that causes a distraction problem. Blinking can be allowed for a short time as long as it stops (or can be stopped)… ‘Flashing’ refers to content that can trigger a seizure… This cannot be allowed even for a second… turning the flash off is also not an option since the seizure could occur faster than most users could turn it off.”

A slowly blinking “Sale ends soon!” badge that a user can pause is a SC 2.2.2 Pause, Stop, Hide concern instead — not fast enough to be a seizure risk. Content flashing faster than three times a second at sufficient size and brightness is a 2.3.1 problem, and no amount of user control fixes that: the fix is not flashing that fast in the first place, not a pause button after the fact.

Where this shows up on e-commerce sites

None of the trigger patterns here are exotic. They’re standard-issue retail marketing tactics:

Animated GIF promo banners. A homepage or category banner built as a looping GIF with a rapid alternating background (a common “attention-grabbing” move for sale callouts) can easily exceed three flashes per second, especially if it was designed by eye rather than measured. Technique G19 notes that a flash is a full light-to-dark-to-light cycle (two opposing transitions) — its own worked example counts seven transitions in a row as 3.5 flashes, already over the limit. The Understanding doc adds a detail specific to GIFs: “for short clips that might be looped… the content should be analyzed while looping” — the moment the loop restarts counts too.

Autoplaying hero or product-teaser video. Fast-cut promotional video — camera-flash effects, rapid scene changes, strobe-lit footage — is exactly the category the criterion was written for. The Understanding doc’s own examples describe “a video clip or animated image of a series of strobe flashes, or close-ups of rapid-fire explosions” as content that can fail. A “flash sale” teaser that leans on an actual flashing-light effect for the pun is worth checking, not assuming safe because it’s short.

CSS-animated urgency UI. A “Only 2 left!” badge or countdown ribbon built with a fast CSS opacity or background-color animation is the pattern most likely to slip through, because it isn’t “media” — it doesn’t get routed through whatever review a video or banner asset gets. A flash or pulse keyframe repeating every 300ms or faster (over 3 cycles/second) can trip the same threshold as a strobing video clip, in three lines of CSS:

/* Risk: a full opacity swing every 250ms is 4 flashes/second -- over the limit */
.low-stock-badge {
  animation: urgent-flash 0.25s infinite;
}
@keyframes urgent-flash {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.2; }
}

/* Safer: slow the cycle below 3 flashes/second, or drop the flash effect
   for a static color + icon change */
.low-stock-badge {
  animation: urgent-flash 1.2s infinite;
}

Technique G19’s rule of thumb makes self-checking easy: keep any full-page-visible animation cycle at three repetitions per second or slower and you’re automatically inside the sufficient technique, no luminance math required.

The small-safe-area exception

Not every fast flash has to slow down. Technique G176 describes the second path to compliance: if the flashing area is small enough (roughly under 25% of a 10-degree visual field at typical viewing distance — about 341×256 pixels on a common reference display), it passes regardless of flash rate. That’s why a small blinking cursor or loading spinner isn’t a seizure risk even though it “flashes” quickly — the area is too small to matter. It’s not a loophole worth designing toward for a marketing banner, though: a banner sized to actually catch a shopper’s attention is usually well past that threshold.

Can an automated scanner catch this?

No — and this is a more fundamental gap than most automated-vs-manual comparisons on this site. A direct check of axe-core’s own rule descriptions turns up exactly one rule anywhere near this territory: blink, which flags the obsolete HTML <blink> element. That rule is tagged for SC 2.2.2 (Pause, Stop, Hide), not SC 2.3.1 — it checks for a deprecated tag, not how fast a CSS animation cycles or how bright a video frame is.

That’s structural, not an oversight: determining a flash-threshold violation requires frame-by-frame luminance and color analysis of rendered visual output over time, a fundamentally different kind of check than parsing DOM structure or CSS values. It’s why the W3C’s own Related Resources for this criterion point to the Trace Center’s Photosensitive Epilepsy Analysis Tool (PEAT) — a dedicated application built to analyze video and animation frame-by-frame — rather than any linting rule or browser extension. A clean axe-core report says nothing about whether a promo GIF is safe; it isn’t built to know.

How to check your own site

  1. Inventory anything that moves fast — autoplay hero/background video, animated GIF banners, and any CSS animation/transition repeating faster than once per second on urgency UI (low-stock badges, countdown ribbons).
  2. For CSS animations, read the keyframe duration directly. A full cycle completing in under about 330ms is at or above three flashes per second — slow it down or drop the effect.
  3. For video/GIF assets with genuine strobe-style effects, use a dedicated tool (PEAT, the one the Understanding doc itself points to) rather than eyeballing it — an effect that looks fine played once can still fail the criterion.
  4. Don’t design toward the small-area exception as a default. It’s a valid pass condition, but a banner sized to be noticed is usually sized past it — control flash rate, not area.

FAQ

Does a slowly blinking “Sale!” badge count? Not under SC 2.3.1, if it’s genuinely slow — that’s a SC 2.2.2 Pause, Stop, Hide question instead (does it stop after five seconds, or can the user stop it), a distraction issue rather than a seizure risk.

What’s the difference between SC 2.3.1 and SC 2.3.2? SC 2.3.1 (Level A) is what a normal WCAG AA audit checks — it allows flashing dim or small enough to fall under the general/red flash thresholds. SC 2.3.2 Three Flashes (Level AAA) is stricter: zero tolerance for anything flashing faster than three times a second regardless of brightness or size — “even a single flashing pixel would violate this criterion,” per its own Understanding doc. Most e-commerce sites target AA, so 2.3.1’s threshold-based version is the one that applies.

Get a full audit that checks what a scanner structurally can’t

A flashing banner or countdown animation can sit on a page with perfectly valid HTML, ARIA, and color contrast — the kind of markup-level issues an automated scan is built to catch — and still fail a criterion that exists purely to protect against a physical health risk. Quietramp’s audits pair an automated axe-core scan with a manual review built to catch exactly this class of gap, delivered as a prioritized, developer-actionable PDF report. See a real sample report or check pricing — $890 one-time, $99/month for ongoing re-checks after fixes ship.


This article is general accessibility information, not legal advice. Meeting WCAG 2.1 AA does not resolve ADA or any other legal compliance question, and nothing here should be read as a compliance guarantee. Consult qualified counsel for legal risk questions.

This article was drafted with AI assistance and reviewed by a person for accuracy before publication.

← Back to Notes