Search topics
Striped backgrounds and op-art hero images that seem to move
A hero background of fine black and white stripes never flashes, yet a still pattern this large can seem to move and can trigger seizures.
background: repeating-linear-gradient(90deg, #111 0 8px, #fff 8px 16px); The problem
People with pattern-sensitive epilepsy can't look at the home page safely, and many others see its stripes shimmer, and some get a headache
A fabric shop launches its summer collection. The designer wants the home page to feel graphic and modern, so the hero is drawn in bold op-art: black and white vertical stripes, each 8 pixels wide, across the full width of the page, with a white card in the middle that reads "The summer edit" and a "Shop the edit" button. Nothing moves. Look at it for a few seconds, though, and the stripes start to shimmer: the edges bend, faint colours run along them, and the whole hero seems to drift. The same failure turns up as an op-art photo or illustration of rings or checks in a hero, a checkerboard or houndstooth background copied from a pattern gallery, a dot grid set close across a section, and stripes one pixel wide that turn into uneven bands when the page is zoomed or scrolled.
No success criterion fails here, and this guide is a best practice. Success criterion 2.3.1 Three Flashes or Below Threshold counts flashes, pairs of opposing changes in brightness over time, and a still image has none, so the hero passes it whatever its contrast and size. Its Understanding document mentions patterns only to exempt fine, balanced ones that flash, such as white noise or an alternating checkerboard. The draft of WCAG 3 adds a requirement against pseudo-motion, defined as static content that gives the perception or feeling of motion, but it is still in development.
The thresholds come from television. The Epilepsy Foundation of America's expert consensus (Harding, Wilkins and others, 2005) treats a pattern as able to provoke seizures when it has clearly visible stripes, more than five light-dark pairs in any orientation. When the stripes cover more than 0.006 steradians from the closest expected viewing distance, the lightest stripe is brighter than 50 cd/m², and the pattern shows for half a second or more, it should have no more than five pairs if it changes direction, oscillates, flashes or reverses, and, if it is unchanging, "no more than eight stripes". ITU-R BT.1702-3 adds that stripes may be parallel or radial, curved or straight, or formed by rows of repeated elements such as polka dots, and in its informative annex it counts a pattern as harmful only when its light and dark bars differ in brightness as much as a harmful flash, and, for a still pattern, only when it fills more than 40% of the screen, a looser area than the quarter the consensus uses. Japan's broadcasters ask for something similar, without figures: NHK and the commercial broadcasters' guideline on animation and other techniques asks them to avoid regular patterns, such as stripes, spirals and concentric circles, that fill most of the screen.
WCAG counts a flash with the same figures in its own terms. It defines 0.006 steradians as a quarter of a 10-degree field, which W3C estimates as 341 × 256 CSS pixels, and a general flash as a change of a tenth of white's relative luminance or more. Applying those to a still pattern is this guide's reading, not a rule anyone has written for the web. By it, the hero fails on every count. Its stripes are black (relative luminance close to 0) and white (1), it holds 80 light-dark pairs at 1,280 pixels wide, and it fills far more than a quarter of the field. At arm's length a CSS pixel is about 0.0213 degrees, so each pair spans about a third of a degree: close to 3 cycles per degree, the spacing Arnold Wilkins and his colleagues found most likely to cause discomfort, illusions and seizures.
Pattern sensitivity is found in most people with photosensitive epilepsy, and matters clinically for about 30 to 50% of them; in one study, 11 of 32 photosensitive patients reacted to still patterns. Stripes at about 3 cycles per degree can also make most people see illusions of colour, shape or movement, and give people with migraine headaches. The Epilepsy Society lists images on screens with a contrasting dark and light pattern, such as black and white stripes or checks, as a possible trigger, and W3C's cognitive accessibility task force names diagonal lines in a background and optical illusions among the pseudo-motion it wants WCAG 3 to cover. A phone held close makes the hero fill even more of what someone sees.
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 For people with pattern-sensitive epilepsy, a large still grating of black and white stripes at this spacing is the kind of image that provokes epileptic activity in laboratory tests, and it is on screen the moment the home page opens.
- Limited language, cognitive and learning abilities The stripes seem to shimmer and drift around the card, pulling the eye away from the heading and the button, so people who are easily distracted struggle to settle on what the page says.
The audit finds nothing here. Its flash check steps through animations and counts changes over time, and this hero never changes. axe, and Lighthouse, which runs axe's rules, have no rule for patterns, and no WCAG criterion gives them one, so the page passes. An AI asked to review the page against WCAG has no reason to raise it either. Meanwhile pattern galleries, such as Lea Verou's CSS3 Patterns Gallery, offer stripes, checkerboards, houndstooth and polka dots as backgrounds to copy, with nothing said about their size or contrast. IRIS, EA's open-source library, checks video for harmful spatial patterns as well as flashes, so a recording of the page can go through it; a person still has to look for patterns in images and count them.
Try it
Apply each fix and see which limit it brings the stripes under
A large striped area is itself the hazard, so the broken hero is covered. Press “Show the stripes” to look briefly. The fixes are safe to view.
Broken Can you fix this?
| Measured | This hero | Under the limit at |
|---|---|---|
| Stripes across | 5 pairs or fewer | |
| Contrast | Under 10% of white | |
| Area | A quarter of a 341 × 256 view |
One measure is under, so the pattern is too. WCAG 2.3.1 passes either way: nothing flashes.
The fix
Use a few broad stripes, or keep fine ones soft or small
<section class="hero"> <div class="hero-card"> <h1>The summer edit</h1> <p>Linen, cotton and canvas, made to last.</p> <a href="/summer">Shop the edit</a> </div></section>What is wrong4 points
- The stripes are 8 pixels wide and repeat every 16, so the hero holds 80 light-dark pairs at 1,280 pixels wide, and more on a wider screen.
- Black against white is close to the strongest contrast a screen can show.
- They fill the whole hero around the card, far more than a quarter of a 341 × 256 pixel field.
- Nothing moves, so no checker reports it.
A few broad stripes
<section class="hero"> <div class="hero-card"> <h1>The summer edit</h1> <p>Linen, cotton and canvas, made to last.</p> <a href="/summer">Shop the edit</a> </div></section>How it is fixed2 steps
- Give the stripe widths in percentages of the hero: 12.5% each, so one light-dark pair is a quarter of its width. The hero holds four pairs at any screen width, under the five both sets of guidelines count from.
- Keep the black and white. Each pair is now 320 pixels wide on a 1,280-pixel screen, about 7 degrees at arm's length: far coarser than the spacing that troubles people most.
This fixes the Before at every width and zoom, and keeps the bold black and white look. 2.3.1 still passes, since nothing flashes.
All three stay under the thresholds on a laptop at 100% zoom. The broad stripes are the recommended one: they keep the black and white and stay under both sets of guidelines at every width and zoom, with nothing to keep in check, while the other two are each partial. Soft stripes keep the fine texture by changing two colours, but the hero still holds dozens of visible stripes; choose them when the pattern is in the background of a page rather than its first view. The small tile keeps the bold fine stripes as a mark, and stays safe only while it stays small. A plain colour or a photograph with no regular pattern needs no measuring at all.
Count the pairs where the eye meets them. A stripe width in pixels means a wider screen shows more stripes, so a hero that looks safe in the design file at 1,280 pixels can hold twice as many on a 2,560-pixel monitor; a width in percentages, or in em on a box of fixed size, keeps the count fixed. A repeating-radial-gradient draws rings, counted from the centre out, and a checkerboard counts along its rows and its columns. BT.1702 counts rows of repeated elements as stripes, so a grid of dots or icons set close in strong contrast is a pattern too.
Never draw stripes one or two pixels wide. In Chromium at a 125% display scale, or at 90% zoom, stripes 1 CSS pixel wide are drawn as uneven runs of one and two device pixels, so the pattern turns into bands the design never had, and the bands change place as the page scrolls: a still pattern that shimmers as it moves. Stripes several pixels wide are rounded too, but by a small part of their width, so they keep their shape.
An op-art image holds the pattern in its pixels, so CSS can't change it. Count its stripes at each size the page shows it, since a responsive image is scaled and cropped differently on each screen. Then fix the image: crop to fewer bands, soften the contrast, or choose another. An SVG pattern drawn with patternUnits="userSpaceOnUse" repeats in the SVG's own units, which are pixels when the SVG has no viewBox, and then gains stripes on a wider screen, as a CSS gradient in pixels does; objectBoundingBox scales the tiles with the shape.
Some changes look like fixes and are not. A switch to hide the pattern, a warning, or a pattern drawn only inside prefers-reduced-motion: no-preference leaves the pattern on screen for everyone who hasn't used the switch or turned the setting on, and it works from the first glance. Text set over the stripes, rather than on the card, has a contrast problem of its own: see low-contrast text on brand colours, photos and hover states.
Stripes that really move are another failure: a scrolling or rotating pattern is covered by tickers, carousels and animations that can't be paused, an animated striped loader by pulsing buttons, glowing badges and endless animations, and parallax by animations that ignore the reduced-motion setting. A pattern that flashes or reverses its contrast is counted under 2.3.1 in flashing banners and videos that can trigger seizures.
Verify the fix
5 checks, no mouse.
Test with: Zoom, Contrast measurement, Flash analysis
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 image or the pattern library changes.
Limits
This is a starting pattern, not a guarantee for every application, and not medical advice. The thresholds were written for television viewed across a room, and carrying them to a web page, through WCAG's own estimate of a 10-degree field, is this guide's reading; a phone held close or a large monitor changes how much of the view a pattern fills. Keeping under them lowers the risk without removing it: the pattern guidelines Wilkins, Emmett and Harding proposed in 2005 are estimated to protect at least two thirds of susceptible people, not all, and some people react to patterns that pass. The audit has no check for patterns, so every one needs a person's eye.
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, and nothing here is medical advice.
References
- WCAG Understanding: three-flashes-or-below-threshold (opens in a new tab)
- w3.org: WCAG22 (opens in a new tab)
- itu.int: R-REC-BT.1702 (opens in a new tab)
- pubmed.ncbi.nlm.nih.gov: 16146438 (opens in a new tab)
- pubmed.ncbi.nlm.nih.gov: 16060930 (opens in a new tab)
- pubmed.ncbi.nlm.nih.gov: 871807 (opens in a new tab)
- www1.essex.ac.uk: 1999-141.pdf (opens in a new tab)
- pmc.ncbi.nlm.nih.gov: PMC6867050 (opens in a new tab)
- tcnet.ne.jp: standard_Exhibit.pdf (opens in a new tab)
- epilepsysociety.org.uk: PhotosensitiveepilepsyApril2025.pdf (opens in a new tab)
- developer.mozilla.org: Accessibility_and_Spatial_Patterns (opens in a new tab)
- w3.org: css-values-4 (opens in a new tab)
- w3.org: wcag-3.0 (opens in a new tab)
- github.com: 739 (opens in a new tab)
- github.com: IRIS (opens in a new tab)
EaseWeb service
Fixed it? Keep it from coming back.
I turn guides like this one into rules your coding agents follow and checks your CI runs. Then I retest by hand with a keyboard and screen readers, periodically.