( Operable / WCAG 2.2.2 )
Page contains a blinking or scrolling element
What is this issue?
The page contains a <blink> element, or CSS setting text-decoration: blink on any element, producing text that toggles between visible and invisible on a fixed interval with no built-in pause, stop, or hide control. <blink> was never a standard HTML element; it was a Netscape-era addition that browsers have since deprecated, and most modern browsers no longer render its blinking effect at all, rendering it as plain static text instead.
Axe-core flags the presence of the element or CSS property itself, regardless of whether a given browser currently renders the blink animation, because the underlying markup is the failure: any browser, extension, or future rendering engine that does honor text-decoration: blink reproduces the exact problem WCAG 2.2.2 exists to prevent.
Why does this matter?
Continuously blinking text is one of the most disruptive patterns a page can put in front of a reader with attention or cognitive disabilities: it demands visual attention by design, competing directly with whatever the user is actually trying to read nearby. For someone with ADHD or a related attention condition, a blinking element in peripheral vision can make it functionally impossible to concentrate on adjacent static content.
Blinking content also interacts badly with assistive technology in a less obvious way: some screen readers re-announce content when the DOM or rendered state changes, so a rapidly toggling element can trigger repeated, disruptive announcements a sighted user never notices happening. There is no legitimate design reason to blink text today: anything blink historically did (draw attention to a notice) is better served by a static, well-designed visual treatment.
Who is affected?
- Cognitive disabilities: continuous blinking competes directly for visual attention with whatever else is on the page, making sustained focus on nearby content difficult or impossible for people with attention-related conditions.
- Low vision users: a rapidly toggling element is harder to track and read around than static content, especially at higher zoom levels where the blinking region occupies more of the visible viewport.
- Screen reader users: a DOM or rendered-state change on a blinking interval can trigger repeated announcements from screen readers that re-read updated content, interrupting whatever else is being read aloud.
What users experience
Owen has ADHD and uses a reading-focus browser extension whenever possible, but it can’t override markup-level blinking. He opens a support article to troubleshoot a billing issue, and a <blink>-styled “Limited time offer!” banner sits in the page’s sidebar, flickering on a roughly one-second interval. He finds himself re-reading the same paragraph of the article three times, his attention pulled to the banner each time it toggles, and eventually closes the tab and calls support by phone instead of finishing the article.
How do I fix it?
Remove <blink> and any text-decoration: blink CSS entirely; there’s no accessible way to keep the blinking effect itself, since the whole point of the rule is that uncontrolled blinking fails regardless of intent. This works because eliminating the animation removes the failure at its source, rather than trying to retrofit pause controls onto markup that was never designed to support them.
If the original goal was to draw attention to time-sensitive or important content, replace it with a static visual treatment (a bold color, an icon, a border, or a badge) that signals importance without motion. If genuine ongoing motion is required, such as a live status indicator, build it as a real CSS animation with a visible, keyboard-operable pause control, which satisfies WCAG 2.2.2 directly instead of trying to make an inherently uncontrollable element controllable.
Code Examples
<blink>Important notice!</blink>
<p style="text-decoration: blink;">Limited time offer!</p><!-- Method 1: static visual treatment (most cases) -->
<p class="notice">
<strong>Important notice:</strong> scheduled maintenance this weekend.
</p>
<!-- Method 2: controllable animation, only if motion is genuinely needed -->
<div class="status-banner" aria-live="off">
<button type="button" aria-pressed="false" onclick="togglePulse(this)">
Pause animation
</button>
<p>Limited time offer - ends Friday</p>
</div>Method 1 removes the animation entirely and replaces it with bold text and a border-driven visual hierarchy, which draws attention just as effectively without moving. Method 2 keeps real motion but adds the pause control WCAG 2.2.2 actually requires; reach for this only when the content genuinely needs to update or animate on its own, not as a default pattern.
Common Mistakes
Mistake: “Blink doesn’t even render in modern browsers, so this warning doesn’t apply to us.” Most current browsers ignore <blink>’s rendering behavior, but the markup itself is still the failure axe-core flags, because any browser extension, older browser, or future rendering engine that does honor it reproduces the exact accessibility problem. Removing the dead markup costs nothing and removes the risk entirely.
Mistake: “We just need to add a pause button to keep this passing.” A pause button is the correct fix for a genuine CSS animation, but <blink> and text-decoration: blink are deprecated, non-standard, and inconsistent across browsers in ways that make retrofitting real user control unreliable. Removing the blink element and rebuilding any needed motion as a proper CSS animation is simpler and more reliable than trying to patch the deprecated one.
Mistake: “A slow blink, once every few seconds, is gentler and doesn’t count.” WCAG 2.2.2 applies to blinking content lasting more than five seconds regardless of the interval; there’s no blink-rate threshold below which the pause/stop/hide requirement stops applying. A slow blink is less jarring than a fast one, but it’s not exempt.
How RedFlag Detects This
Automated: axe-core rule, runs on every scan. RedFlag calls axe-core’s blink rule as part of every scan, restricted to the WCAG 2.0/2.1/2.2 A and AA rule set. The rule checks for the presence of any <blink> element or any element with a text-decoration value containing blink, and flags it regardless of whether the current browser actually renders the blinking effect.
False negative: the check only looks for the literal <blink> element or the blink CSS keyword; a JavaScript-driven setInterval toggling an element’s visibility or opacity on and off produces the identical user-facing problem but leaves no matching markup for this rule to find. False positive: none typical, since the presence of the deprecated element or CSS keyword is a straightforward, binary parse of markup already on the page. Manual step: watch the live page for any script-driven flickering effect that reproduces the same continuous, uncontrollable toggling this rule targets, since the automated check can’t see JavaScript-based blinking.
Manual Testing
- Load the page in a browser and watch for at least ten seconds without interacting. Note any text or element that visibly flickers or toggles on and off.
- View the page source (or DevTools Elements panel) and search for
<blinkortext-decoration: blinkin any inline style or stylesheet. - If any blinking effect is present, confirm whether a visible, keyboard-operable pause, stop, or hide control exists nearby; if not, the check fails.
- With NVDA or VoiceOver running, navigate near the blinking element and confirm it isn’t triggering repeated, disruptive re-announcements of nearby content.
Related WCAG Success Criteria
2.2.2 Pause, Stop, Hide: For any moving, blinking, scrolling, or auto-updating content that starts automatically and lasts more than five seconds, the user must be able to pause, stop, or hide it, unless the movement is essential. Uncontrolled blinking with no such control is a direct failure of this requirement.
Related Issues
marquee element is used is the equally obsolete, equally uncontrollable sibling of this rule: scrolling motion instead of blinking, flagged by the same axe-core detection approach and mapped to the identical 2.2.2 criterion.
Page has no way to bypass repeated content shares this rule’s Operable-principle concern with giving users control over what they’re forced to process, though it addresses navigation repetition rather than motion.
Multiple links go to the same destination with different text and Link has no accessible name commonly appear in the same legacy-markup audit as blink and marquee; all are patterns from older, less disciplined HTML that modern semantic markup replaces cleanly.
Link opens a file with no format or size warning and Link text is generic and gives no context are other legacy-content patterns worth auditing together with obsolete elements like this one, since sites that never removed <blink> often haven’t revisited their link text either.
References
Frequently asked questions
Is the deprecated blink element the only thing this rule flags?
No. Axe-core's blink rule also flags a text-decoration: blink CSS declaration, which produces the identical flickering effect without using the obsolete HTML element at all. Both trigger the same failure for the same reasons.
Do modern browsers even render the blink element anymore?
Most current browsers stopped implementing blink years ago, so the element often renders as static, non-blinking text today. The rule still flags it because relying on a browser silently ignoring deprecated markup is not a real fix, and any browser or extension that does still support it reintroduces the original failure.
What's the difference between blink and redflag-flash?
This rule concerns continuous, uncontrollable blinking with no pause option, a Pause-Stop-Hide failure under 2.2.2. Content flashing more than 3 times per second is a separate, more severe seizure-risk criterion (2.3.1), covered by redflag-flash, that applies regardless of whether a pause control exists.
Does a CSS animation that blinks slowly, like once every 3 seconds, still fail this check?
Yes, if it runs continuously with no way to pause, stop, or hide it. WCAG 2.2.2 applies to any moving, blinking, or auto-updating content lasting more than five seconds total, regardless of how slow the blink rate is; the requirement is about user control, not blink speed.
Can I keep a blinking effect if I add a pause button?
Yes. WCAG 2.2.2 does not ban blinking content outright; it requires that the user be able to pause, stop, or hide it. A blinking element with a working, keyboard-accessible pause control satisfies the requirement without removing the animation.