Modal
<allegro-modal> is a centered dialog over the whole page, with a backdrop. Use
it for a welcome note, an announcement or a short prompt that the reader reads
and then closes. A Modal is always dismissible. To block reading until the
reader signs up, use a Content Gate instead.
The Modal opens as soon as it renders. It has no delay, trigger or frequency options: the interaction that places it decides whether and when it shows. Once the reader dismisses it, it stays closed for the rest of the visit (see Remembering a dismiss). While it is open, the rest of the page is inert, focus stays inside the dialog, and page scroll is locked.
Usage
<allegro-modal>
<h2>Welcome to Acme News</h2>
<p>Here is what is new this week.</p>
<button type="button" data-allegro-close>Get started</button>
</allegro-modal>
A large Modal holding a form, so a stray backdrop click does not close it:
<allegro-modal size="large" close-on-backdrop="false">
<h2 data-allegro-title>Get our weekly newsletter</h2>
<p>The best of our reporting, every Friday.</p>
<allegro-email-form></allegro-email-form>
</allegro-modal>
The component does not lay out its content. Style the slotted markup in the template's CSS field.
Accessibility
The Modal names itself from the first of these that exists:
- The
labelattribute. - An element in its content marked
data-allegro-title. - The first
h1–h6in its content.
The close button is named "Close". Mark decorative elements
aria-hidden="true".
On open, focus moves to the first focusable element in the content, or to the
close button when there is none. Add autofocus to any element to focus it
instead, including a heading with tabindex="-1". On close, focus returns to
the element that had it before the Modal opened.
Closing
Every close records a method, which says how the Modal was closed. It is sent
with the dismiss_modal event and the allegro:modal:closed event.
| Method | Cause |
|---|---|
escape | The reader presses Escape. |
close-button | The reader clicks the built-in close button. |
backdrop | The reader clicks the backdrop, unless close-on-backdrop="false". |
action | A click on or inside a data-allegro-close element, or a slotted form's Continue button. |
api | close() or the allegro:modal:close event. |
A data-allegro-close link closes the Modal and is then followed as normal. The
Modal does not close when the reader logs in.
// From site code or an Alpine template.
document.querySelector('allegro-modal').close();
Remembering a dismiss
When an interaction places the Modal, a dismiss is remembered until the browser
closes. On later pages in the same visit, the Modal doesn't open, so it doesn't
lock scroll or track view_modal. Every close method counts.
- Each interaction is remembered separately, by its slug. Dismissing one interaction's Modal does not hide another's.
- The state is kept in a session cookie named
allegro_modal_{slug}, shared across tabs and set on your organization's cookie domain when it has one. - A Modal that your site's code or theme renders directly, rather than through an interaction, has no slug and remembers nothing.
To see a dismissed Modal again while testing, close the browser or delete its cookie.
The interaction still runs on later pages, so its frequency caps still count those deliveries even though the Modal does not show.
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
size | text | medium | The dialog's maximum width: small (u(28)), medium (u(36)), large (u(52)) or full. See CSS Variables for u(n). |
position | text | center | Where the dialog sits: center, or top, which places it near the top of the screen with --modal--top-offset of space above it. |
close-on-backdrop | boolean | true | Close the Modal when the reader clicks the backdrop. Turn off for Modals that hold a form. |
label | text | (empty) | Accessible name. Overrides the title element and the first heading. |
tracking-data | text | (empty) | JSON object of custom data merged into every tracked event, e.g. "{'campaign': 'welcome'}". |
Events
Dispatched
| Event | Bubbles | Detail | Description |
|---|---|---|---|
allegro:modal:open | yes | (none) | Fired on the element once the Modal opens. |
allegro:modal:closed | no | { method: string } | Fired on window once the Modal has been removed. |
Listened to
| Event | Detail | Description |
|---|---|---|
allegro:modal:close | (none) | Dispatch on the element, or from inside it, to close it. |
allegro:content-gate:close | (none) | A slotted Email Form's Continue button closes the Modal. |
allegro:login-form:continue | (none) | A slotted Login Form's Continue button closes the Modal. |
document
.querySelector('allegro-modal')
.dispatchEvent(new CustomEvent('allegro:modal:close'));
window.addEventListener('allegro:modal:closed', (event) => {
console.log('Modal closed:', event.detail.method);
});
Tracked Events
The component records the following events via the Allegro SDK.
| Event | When | Data |
|---|---|---|
view_modal | Fired when it opens. | { size: string } |
dismiss_modal | Fired when it closes. | { size: string, method: string } |
CSS Variables
Set the variables in the template's CSS field. Most can also be set for your whole organization in Branding.
allegro-modal {
--modal--background: #fffaf0;
--modal--max-width: 40rem;
}
Don't set them with a style attribute on the element. Components accept only
their own attributes and log an error for style, class and id.
Defaults written below as u(n) mean n times --modal--base-font-size, the
component's sizing unit: u(0.5) is half that unit, u(2.5) is two and a half.
The unit defaults to --allegro--font-size, then the page's rem. If the host
page sets a root font-size other than the usual 16px, pin it so the Modal
sizes the same either way:
allegro-modal {
--modal--base-font-size: 16px;
}
Dialog
| Variable | Default | Description |
|---|---|---|
--modal--base-font-size | var(--allegro--font-size, 1rem) | Base sizing unit for the component. |
--modal--max-width | (from size) | An exact dialog width. Overrides size. Not a Branding variable. |
--modal--background | #fff | Dialog background. Falls back to --allegro--color-background. |
--modal--color | #000 | Dialog text color. Falls back to --allegro--color-text. |
--modal--font-family | (none) | Dialog font family. Falls back to --allegro--font-family. |
--modal--padding | u(2) | Padding around the content. Content can sit under the close button; pad your own markup to keep it clear. |
--modal--border-radius | u(0.375) | Dialog corner radius. Falls back to --allegro--radius. |
--modal--max-height | 100% | Maximum dialog height. The default is the screen height less u(1) above and below. Taller content scrolls inside the dialog. |
--modal--top-offset | u(4) | Space above the dialog when position is top. |
--modal--transition-duration | 0.25s | Length of the open and close animation. Capped at 0.15s under reduced motion. |
Overlay
| Variable | Default | Description |
|---|---|---|
--modal--overlay--background | rgb(0 0 0 / 0.6) | Backdrop color. |
Close button
| Variable | Default | Description |
|---|---|---|
--modal--close--size | u(2.5) | Width and height. |
--modal--close--color | currentColor | Icon color. |
Buttons in your content
The Modal does not style your buttons. It resolves a button color for you to use
in the template's CSS, from --modal--button--background and
--modal--button--color, then the global button tokens.
| Variable | Default | Description |
|---|---|---|
--modal--button--background | #000 | Set in Branding. Read it as var(--modal-button-background) in template CSS. |
--modal--button--color | #fff | Set in Branding. Read it as var(--modal-button-color) in template CSS. |
.welcome-button {
background: var(--modal-button-background);
color: var(--modal-button-color);
}
Parts
Style the component's own elements with ::part().
| Part | Element |
|---|---|
dialog | The visible dialog box. |
backdrop | The backdrop behind it. |
close | The close button. |
body | The scrolling area around your content. |
Motion
The dialog fades in and scales up slightly, and the backdrop fades in. Both
reverse on close. When the reader has asked for reduced motion, the Modal only
fades. Browsers without @starting-style show it without animation.
Example: Dark announcement
allegro-modal {
--modal--background: #111827;
--modal--color: #f9fafb;
--modal--overlay--background: rgb(17 24 39 / 0.8);
--modal--border-radius: 1rem;
}
allegro-modal::part(dialog) {
box-shadow: none;
}