Search topics
Timed pop-ups that open while you read or type
A sign-up pop-up opens ten seconds after the page loads, whatever people are doing, and nothing on the page lets them put it off or turn it off.
setTimeout(() => signup.showModal(), 10000); The problem
People reading or typing on the page have a pop-up they didn't ask for opened over their work, and nothing lets them put it off or turn it off.
Fernleaf Paper sells greeting cards and posts them for you. The shop wants new visitors' email addresses, and its pop-up is drawn with care: a soft card over the dimmed page, "Get 10% off your first order", one email field, a Sign up button and a × in the corner. It opens ten seconds after a page loads, a delay set in the shop's marketing tool so that it never greets people the moment they arrive.
On the page for a wildflower birthday card, someone is writing the message to go inside it. They have typed "Happy birthday! Hope you" when the ten seconds are up. The pop-up opens over the page and focus moves into its email field, so "have a lovely" goes into the email address instead of the card. A screen reader user who was reading the card's description hears the pop-up's heading and field in its place. Someone who finds it hard to hold their attention is now looking at an offer, not at the message they were halfway through. The × and Escape close the pop-up, and nothing on the page lets anyone put it off or turn it off before it comes.
Success Criterion 2.2.4 Interruptions (Level AAA) asks that interruptions can be postponed or suppressed by the user, except interruptions involving an emergency. Its Understanding page puts the intent as letting people turn off updates from the author or the server, and its one example is a preferences page with an option to postpone all updates and alerts until the end of the session. W3C's technique G75 does it through a preference, or by warning people that an update is about to come and letting them suppress it; G76 lets people ask for the update instead.
The pop-up offers neither. It has a × and closes on Escape, but both come after the interruption: by the time either can be pressed, the sentence has been broken off. Nothing before it lets anyone choose not to have it, or to have it later.
The browser has no reason to hold it back. A timer runs whether or not anyone is in the middle of something, and showModal() does what a modal dialog should: it puts the dialog over the page, makes the page behind it inert and moves focus into it, here to the field marked autofocus. Every part of the pop-up is built right. What fails is when it opens.
The timer was chosen so that the pop-up doesn't open the moment people arrive. Ten seconds is long enough to have started something, so it lands on people while they are doing what they came for, and the more slowly they read or type, the more likely they are to be in the middle of it.
4 of 10 groups affected
- No vision (affected)
- Low vision (affected)
- Colour vision (not affected)
- No hearing (not affected)
- Hard of hearing (not affected)
- No speech (not affected)
- Motor (affected)
- Reach, strength (not affected)
- Cognitive (affected)
- Seizures (not affected)
- Limited language, cognitive and learning abilities People with attention difficulties, the first group W3C names for this criterion, lose the thread of the message they were writing or the text they were reading when the pop-up takes over the page, and finding it again costs far more than the press that closes the pop-up.
- Without vision Focus moves into the pop-up's email field, and the screen reader follows it there: it moves on to the pop-up's heading and field from whatever was being read, and once it closes, finding the place again is up to them.
- Limited manipulation Keyboard and switch users, and people dictating the message with voice control, go on typing into the pop-up's email field after focus has moved there, and then have to delete it, close the pop-up and get back to the message.
- Limited vision A screen magnifier that follows focus jumps from the message to the pop-up, so the part of the page that was being read leaves the view.
Nothing in the markup is wrong, and a scan that loads the page and leaves within a few seconds is gone before the pop-up opens. The audit watches the timers a page starts before anyone has used it, and sends one whose callback calls showModal(), or a function named like openPopup(), to review as ew:timed-popup-manual-check: only a person can tell whether a setting already turns it off, or whether it is an emergency. Pop-ups from a marketing tool are often set up in its dashboard and loaded through code the audit can't recognise, and a chat greeting is set on the chat vendor's side, so the audit misses those; the dashboards have to be checked by hand. Asked for "a newsletter pop-up after ten seconds", AI coding tools write a setTimeout like the one in the Before.
Try it
Write a message to go inside the card, and take your time over it.
The shop’s ten seconds start when you first click or Tab into the page, and the demo clock counts them. Keep typing past ten seconds and see where your words go. Then apply each fix: press Get 10% off when you want the offer, or untick the setting before the time is up, and press Start over to load the page again.
Broken Can you fix this?
Fernleaf Paper
Wildflower birthday card
$4.50 · Pressed-flower print on recycled card. We write your message inside and post it for you.
The fix
Open the offer when people ask for it.
<main> <h1>Wildflower birthday card</h1> <form class="card-form"> <label for="card-message">Message inside the card</label> <textarea id="card-message" name="message" rows="4"></textarea> <button>Add to basket</button> </form></main><dialog id="signup" aria-labelledby="signup-title"> <button type="button" class="signup-close" aria-label="Close">×</button> <h2 id="signup-title">Get 10% off your first order</h2> <p>Sign up for news of new designs and sales.</p> <form method="dialog"> <label for="signup-email">Email address</label> <input id="signup-email" name="email" type="email" autocomplete="email" autofocus required> <button>Sign up</button> </form></dialog>What is wrong3 points
The pop-up itself is right: it is a native dialog, its × is a named button, Escape closes it, and closing it puts focus back where it was. Where it fails is when it opens.
- It opens ten seconds after the page loads, whatever the person is doing at that moment.
- Focus moves into the email field, so typing meant for the card goes into the pop-up, and a screen reader stops reading the page to read the pop-up.
- Nothing on the page lets anyone put it off or turn it off before it comes.
A button that opens the offer
<p class="offer-bar"> New here? <button type="button" id="offer-open">Get 10% off your first order</button></p><main> <h1>Wildflower birthday card</h1> <form class="card-form"> <label for="card-message">Message inside the card</label> <textarea id="card-message" name="message" rows="4"></textarea> <button>Add to basket</button> </form></main><dialog id="signup" aria-labelledby="signup-title"> <button type="button" class="signup-close" aria-label="Close">×</button> <h2 id="signup-title">Get 10% off your first order</h2> <p>Sign up for news of new designs and sales.</p> <form method="dialog"> <label for="signup-email">Email address</label> <input id="signup-email" name="email" type="email" autocomplete="email" autofocus required> <button>Sign up</button> </form></dialog>How it is fixed3 steps
- Delete the timer, so the pop-up never opens by itself.
- Put a button at the top of the page that says what it opens, "Get 10% off your first order". The offer is in front of every visitor from the moment the page loads, and in the same place on every page.
- Open the same pop-up from that button. Focus moves into the email field only because someone pressed the button, and closing the pop-up brings them back to it.
This fixes the Before and passes 2.2.4: nothing opens until it is asked for, so there is nothing to put off. The pop-up keeps its look; what changes is a slim bar at the top of the page that is there from the start.
Why this fix: Change the page only when people ask
The button passes 2.2.4 as technique G76 describes it; the setting meets the criterion's wording but not G75's test. The button is recommended: nothing interrupts anyone, so nobody has to find a setting first, while the setting is not enough on its own, because the pop-up still opens over the work of everyone who hasn't found it yet. The button costs the shop the visitors who would only have signed up when the offer was put in front of them; a bar at the top of every page keeps the offer in view without stopping anyone. Keep the setting only when the timed pop-up has to stay, put it first on the page, and remember the choice.
Other triggers that nobody presses. Marketing tools also open pop-ups when the visitor has scrolled part of the way down, has been on the site for a while, or moves the pointer towards the address bar, as if to leave. Each of these opens without being asked for, in the middle of whatever the person is doing, and takes the same fix: open it from a button, or put it behind the setting.
Remembering that the pop-up was closed. Marketing tools can be set to stop showing a pop-up for some days once it has been closed. That spares people a second interruption, which is worth doing, but the first one still comes, and nothing before it lets anyone say no, so it doesn't fix the Before on its own.
A chat that greets people by itself. Chat tools can send a greeting a set time after someone arrives, and pop the chat widget up with it: Zendesk's default Proactive Greeting trigger, inactive until a site turns it on, sends one to new visitors 30 seconds after they arrive. It is the same failure. Leave the greeting for when the panel is opened from its launcher, or put it behind the same setting. How the launcher and its panel are reached is the subject of chat buttons that Tab skips, and close buttons with no name, and whether its messages are read out, of chat widgets that never announce their messages.
Update prompts. A web app that has a new version can tell people quietly, in a line or a button that waits ("A new version is ready. Reload"), instead of a dialog over their work. Reload when they press it.
Emergencies may interrupt. WCAG's emergency is a sudden, unexpected situation that needs action at once to protect health, safety or property, and the Understanding page counts messages that warn of data loss or a lost connection among them. A warning that a session is about to end and take the order with it may interrupt, and should, as session timeouts with no warning or way to extend describes. A sale that ends tonight is not an emergency. How such a message is announced, and why routine news should wait for the screen reader, is in alerts that cut off VoiceOver for routine updates.
Pages that reload themselves. A page with <meta http-equiv="refresh"> interrupts by reloading, and W3C's failure F41 counts it against 2.2.4 as well as 2.2.1 and 3.2.5. Delete it, as pages that reload or redirect themselves on a timer shows; a list that rewrites itself on a timer is auto-updating feeds that change while people read them.
The pop-up itself. This guide is about when a pop-up opens. Once it is open, it still needs a keyboard way out, as in pop-ups that can't be closed with a keyboard, and focus kept inside and brought back, as in modals that leave keyboard focus behind them.
Design ideas
An offer can stay in view without stopping anyone
Three more places for the sign-up that wait to be asked, and two fashionable ones that open by themselves. Tab or move the pointer into each sample, and press what it offers.
In the design file
- Draw where the offer sits on the page at rest, on a phone and a wide screen, and the pop-up only as what its button opens.
- Write on the button what it opens, such as “Get 10% off your first order”, not “Click here”.
- Mark where focus goes when the pop-up opens, and that it goes back to the button when the pop-up closes.
- If a timed pop-up has to stay, draw the setting that turns it off at the top of the page, and the page with it off.
Passes
Fernleaf Paper
Wildflower birthday card
$4.50 · Pressed-flower print on recycled card.
10% off your first order
A sign-up band inside the page A warm paper band between the card’s details and the next section, with its own heading, one field and a green Sign up pill, white on #2f5d50 at 7.49:1. Nothing covers the page; people meet it when they scroll to it, and it shows the whole offer without a press.Fernleaf Paper
Wildflower birthday card
$4.50 · Pressed-flower print on recycled card.
A “10% off” tab, there from the start A small green tab with a gift icon, fixed to the edge of the screen near the bottom, there as soon as the page loads, that never moves or grows by itself. Pressing it opens the sign-up beside it, with focus in the field; × or Escape closes it and puts focus back on the tab. Keep it clear of the content and of the focused control.Rule of thumb: Change the page only when people ask
Your basket
Wildflower birthday card $4.50
Total $4.50
Sign up and save $0.45 on this order.
The offer beside the basket total A quiet line under the total, “Sign up and save $0.45 on this order”, in brown #6b5d4f at 6.36:1, with a Get 10% off button after it. The offer comes where the saving means something, and only opens the sign-up when it is pressed.
Fails
- A slide-in once half the page is readWCAG 2.2.4 Tab or move the pointer into the sample and wait: the sign-up slides up over the lower half of the page and takes focus. It feels less pushy than a full pop-up, but it still opens in the middle of whatever people are reading or typing, and nothing lets them say no first. The sample does it once.
Rule of thumb: Change the page only when people ask
Fernleaf Paper
Wildflower birthday card
$4.50 · Pressed-flower print on recycled card.
A spin-to-win wheel on arrivalWCAG 2.2.4 A bright wheel of prizes covers the page a moment after it opens, with Spin to win and a small “No thanks”. It is playful, but it stands between people and the page they came for, and the only choice it leaves them is to close it once it is there.Rule of thumb: Change the page only when people ask
Verify the fix
5 checks, no mouse.
Test with: Keyboard, Screen reader
Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after any change to the pop-up, the tools that show it, or their campaigns.
Limits
This is a starting pattern, not a guarantee for every application. It covers one sign-up pop-up opened on a timer. The snippets leave out what Sign up does with the address. Marketing and chat tools change their settings and campaigns without a deploy on your side, so their pop-ups need checking again after each change. Whether an interruption is an emergency is a judgement about your service, not something code can decide. Test the complete journey with the assistive technology your visitors use.
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.
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.