Just launchedPattern Paste: copy-paste WordPress block patterns and theme styles

Exit-Intent Promo Popup

£5 Standard License Unlimited projects

An exit intent popup for promo codes and email capture: exit, scroll-depth, delay and manual triggers, shown once per session or per N days, an accessible modal with a two-panel split entrance and a button that morphs into its sent state.

intermediate
7 more details
dialog-animationfocus-managementmask-revealstaggerform-animationstate-transitionkeyboard-navigation

About This Component

An exit intent popup with the trigger rules a real promo or newsletter popup needs. It opens when the pointer leaves through the top of the viewport, when the reader scrolls past a chosen depth, after a time delay, or when your own code calls it, and each rule is a data attribute on the component root. It remembers that it has been shown, once per session or once per N days, so nobody sees the same discount popup twice in a visit.

Read the full effect overview

It is a proper modal, not a floating div: role=dialog with aria-modal, focus moves to the email field on open, is trapped while the dialog is open and is handed back when it closes, Escape and the backdrop dismiss it, and the page behind is scroll-locked with the scrollbar gap compensated so nothing shifts. The dialog is hidden for real when closed, so an invisible layer never covers the page.

The entrance is the part a buyer would not hand-roll. The backdrop fades in while its blur ramps up from zero, the offer panel and the content panel slide in from opposite sides and meet in the middle, the headline words rise through a mask one after another, the body and the email field follow, and the button lands last with a small scale-in. Submitting hands the email out as an event for your provider and morphs the button into a "Code sent" state before the dialog closes itself. On a phone the card becomes a bottom sheet and rises instead of splitting. Three shipped looks, light, dark and indigo, defined entirely in CSS custom properties: dark is the same design re-valued, not a second skin.

What's Included

10 items
  • Four trigger rules on one attribute: exit intent, scroll depth, time delay and manual
  • Exit intent fires when the pointer leaves through the top edge, with a cooldown after load
  • Shown once per session, once per N days, or every time, stored under a key you choose
  • Touch fallback: scroll and delay still work, plus an optional fast-scroll-up rule for phones
  • Accessible modal: role=dialog, aria-modal, focus trap, focus return, Escape and backdrop close
  • Body scroll lock with scrollbar-gap compensation, and the dialog is hidden for real when closed
  • Split entrance: backdrop blur ramp, panels meeting from opposite sides, headline words rising through a mask
  • Submit morphs the button into a sent state and dispatches the email as a popup:submit event
  • Bottom-sheet layout under 640px with full-width controls and a rise instead of the split
  • GSAP core only, and three shipped looks: light, dark and indigo

Perfect For

5 use cases
  • Ecommerce discount popup that catches a visitor about to leave the cart
  • Newsletter popup on a blog, shown after a scroll depth that proves they were reading
  • Lead magnet or email capture modal on a landing page, shown once per week per visitor
  • Promo code announcement for a sale window, opened by your own button or script
  • Abandonment offer on a pricing page, triggered by exit intent on desktop and delay on mobile

How It Works

3 sections

Trigger rules on the root

data-trigger takes a space-separated list of exit, scroll, delay and manual. Exit intent is a mouseleave on the document element whose clientY is at or above zero, listened for on fine pointers only and ignored during a short cooldown after load. Scroll depth reads scrollY against the page's scrollable height. The delay is a setTimeout from load. All of them go through one gate that checks the popup is armed, not already open, not already shown on this page load, and not already shown for the current session or window, which is read from sessionStorage or a timestamp in localStorage depending on data-once. The once-per-load rule covers exit intent too, so the popup never reappears the second time the pointer heads for the tab bar; only the manual open() bypasses it.

The split entrance

The backdrop's opacity tweens while a plain object carries its blur radius from 0 to the variant's --backdrop-blur, written to backdrop-filter on every update. The two panels start at xPercent -18 and +18 with opacity 0, set by gsap.set rather than CSS so no transform is left behind, and tween to 0 on power4.out inside a card with overflow hidden. The headline is split into word spans at init, each in an overflow-hidden mask, and they rise from yPercent 110 with a 0.04s stagger; the body and field fade up after them and the button scales in from 0.92. Closing is a shorter timeline on power2.in: content fades, the panels part by 6%, the card drops 24px and fades, and the backdrop blur unwinds. hidden is set on the root in onComplete so the closed popup never covers the page.

Focus, scroll lock and the phone

The previously focused element is remembered on open, the email field is focused with preventScroll, and one document-level keydown handler traps Tab within the dialog and closes on Escape. The page behind is locked on both <html> and <body> (body's overflow only reaches the viewport while html's is visible), with the scrollbar's width added as padding and the scroll offset restored on close, so the reader lands back exactly where they opened it. Under 640px a matchMedia check at open time switches the entrance to a yPercent rise for the bottom sheet, and the CSS collapses the card to a single column with the offer panel as a strip. Submitting prevents the form's default, dispatches popup:submit with the email, tweens the button's background to the success colour while the label crossfades, and closes the dialog 1.6 seconds later.

Difficulty Intermediate
Includes HTML + JS + CSS source, documentation, AI setup prompt, lifetime updates
£5

Premium UI Element

Exit-Intent Promo Popup

Purchase this ui element to unlock the full source code and implementation.

£5 Standard License Unlimited projects
Browse UI Elements

Your Cart

Your cart is empty

The Vault £99

Every effect, template and UI element: 158 today, plus everything we release next.