Remove or reduce intrusive interstitials on mobile
Intrusive interstitials are dialogs and overlays that cover the main content immediately after a page loads. They block the content the customer came for, and Google's search guidance advises against them. Replacing them with inline content, a compact banner, or a dialog that appears only after the customer engages keeps the page usable on a small screen.
On a phone, an overlay that appears on arrival covers most of the screen. The customer has to find and hit a close control before they can read anything, and the close control is often the smallest tap target on the page.
Intrusive interstitials cause specific problems:
- Blocked content: customers have to dismiss the overlay before they can reach what they came for.
- Search guidance: Google's guidance on mobile interstitials specifically calls out content that's covered immediately after a customer arrives from search.
- Loading metrics: a dialog injected during page load can become the Largest Contentful Paint element, which makes your LCP reflect the dialog rather than your content. For more information, refer to Prevent dialogs from hijacking LCP.
- Accessibility issues: a dialog that appears without warning, without a focus trap, and without a focus return is hard to use with a screen reader or a keyboard.
Google describes intrusive interstitials as:
- Dialogs that cover the main content immediately after the customer navigates from search.
- Standalone interstitials that the customer must dismiss before they can access the content.
- Layouts where the content in the initial viewport looks like a standalone interstitial.
Anchor to Don't cover the content on arrivalDon't cover the content on arrival
The strongest version of this fix is to not show a dialog on load at all. Anything that a customer sees before they've asked for it competes with the content, so start by asking whether the message can live in the page instead of on top of it.
If you keep a dialog, then gate it on an interaction, such as a scroll, a tap, or a click, rather than on a timer. A timed reveal on a page that the customer hasn't touched still covers the content, and it can also become your LCP element. For the loading-metrics side of that decision, and for the interaction-gating pattern, refer to Prevent dialogs from hijacking LCP.
Anchor to Use an inline signup instead of a dialogUse an inline signup instead of a dialog
Put the signup in the content flow, where it doesn't block anything:
A compact bar at the bottom of the screen leaves the content readable:
Anchor to Show a dialog only after the customer engagesShow a dialog only after the customer engages
If you do use a dialog, then build it with the native <dialog> element and open it with showModal(). That gives you a focus trap, focus restoration on close, Escape handling, an inert background, and the ::backdrop pseudo-element without writing any of it yourself.
The following example is complete: the markup, the styles, the eligibility check, and the two triggers all refer to the same dialog. It opens after the customer has scrolled past half of the page or moved the pointer out of the top of the window, and only if they haven't seen or dismissed it recently:
Exit intent works with a pointer only, so a touch-only session relies on the scroll trigger. Don't add a timer as a fallback for touch, because that reintroduces the untriggered reveal that this page is about.
Anchor to ExamplesExamples
Anchor to Convert a dialog to an inline sectionConvert a dialog to an inline section
The following dialog covers the content as soon as the page loads:
Moving the same offer into the page removes the problem entirely:
Anchor to TestingTesting
-
Mobile device testing: load the page on a phone, arriving from a search result, and confirm that you can read and use the main content without dismissing anything.
-
Trigger testing: confirm that the dialog opens only after a scroll or an exit-intent gesture, and that it doesn't open at all on a page you load and leave untouched.
-
Keyboard and screen reader testing: open the dialog, then verify that focus moves into it, that
Tabstays inside it, thatEscapecloses it, and that focus returns to where it was before the dialog opened. -
Dismissal testing: dismiss the dialog, reload the page, and confirm that it stays closed for as long as your eligibility check says it should.
-
Loading metrics: run a Lighthouse mobile audit and confirm that your LCP element is still the main content rather than the dialog or the banner. For more information, refer to Prevent dialogs from hijacking LCP.
Anchor to ReferencesReferences
- Google: helping users easily access content on mobile
- MDN: the dialog element
- Nielsen Norman Group: modal and nonmodal dialogs
- ARIA Authoring Practices Guide: dialog pattern
- Prevent dialogs from hijacking LCP