Modal
Overlay dialogs built on the native HTML dialog element — sizes, fullscreen breakpoints, scroll containment, sequential transitions, and a data-attribute API.
Introduction
A modal is a <dialog> element styled with .modal and activated by the .dialog plugin. The two classes have distinct responsibilities:
.dialog— behavior: animation, backdrop, keyboard handling, and the open/close lifecycle..modal— visual style: colors, borders, shadows, and layout of the header, body, and footer regions.
<dialog class="modal dialog" id="exampleModal" aria-labelledby="exampleModalLabel">
<div class="modal-header">
<h2 class="modal-title" id="exampleModalLabel">Modal title</h2>
<button type="button" class="close-button" data-cx-dismiss="dialog" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>Modal content goes here.</p>
</div>
<div class="modal-footer">
<button type="button" class="button primary">Take action</button>
<button type="button" class="button default" data-cx-dismiss="dialog">Close</button>
</div>
</dialog>Chassis CSS respects user accessibility preferences by automatically disabling animations when the prefers-reduced-motion media query is detected. See the reduced motion guidelines in our accessibility documentation for implementation details.
Basic structure
A modal is composed of a <dialog> element with .modal.dialog and up to three region children:
.modal-header— flex row containing the title and a.close-button. A direct-child.close-buttonis positioned absolute at the block-start / inline-end corner of the header automatically..modal-body— main content area. Takes the remaining height when.scrollableis applied (see Scrollable)..modal-footer— flex row, right-aligned, for action buttons.
All three regions are optional. The plugin calls showModal() to place the element in the browser's top layer, which provides automatic position: fixed centering and a native ::backdrop — no wrapper elements needed.
For critical confirmations and decision-forcing dialogs, see Alert. For full-height side panels, see Drawer.
Live example
To open a modal, add data-cx-toggle="dialog" to any trigger element. For buttons, point at the <dialog> with data-cx-target="#id". For links, set href="#id" instead — data-cx-target is not needed. The close button and Cancel both dismiss it; clicking outside or pressing Escape also closes it by default.
<button type="button" class="button primary" data-cx-toggle="dialog" data-cx-target="#exampleModalLive">Show modal</button>
<a href="#exampleModalLive" class="button link" data-cx-toggle="dialog">Show modal</a>
<dialog class="modal dialog" id="exampleModalLive" aria-labelledby="exampleModalLiveLabel">
<div class="modal-header">
<h2 class="modal-title" id="exampleModalLiveLabel">Modal title</h2>
<button type="button" class="close-button" data-cx-dismiss="dialog" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>Modal body content goes here.</p>
</div>
<div class="modal-footer">
<button type="button" class="button primary">Take action</button>
<button type="button" class="button default" data-cx-dismiss="dialog">Close</button>
</div>
</dialog>Layout options
The classes below control the dimensions and scroll behavior of the modal window. All size and fullscreen modifiers apply directly to the <dialog> element alongside .modal.dialog.
Sizes
Add a size modifier to change the modal width. Without a size modifier the modal renders at 560px.
| Class | Width |
|---|---|
.modal.small | 360px |
.modal (no modifier) | 560px |
.modal.large | 800px |
.modal.xlarge | 1140px |
Fullscreen
Add .fullscreen to expand the modal to the full viewport. The responsive max-{breakpoint}:fullscreen variants go fullscreen only below the named breakpoint — above it the modal renders at its normal size.
| Class | Behavior |
|---|---|
.modal.fullscreen | Always fullscreen |
.modal.max-small:fullscreen | Fullscreen below small (576px) |
.modal.max-medium:fullscreen | Fullscreen below medium (768px) |
.modal.max-large:fullscreen | Fullscreen below large (1024px) |
.modal.max-xlarge:fullscreen | Fullscreen below xlarge (1280px) |
.modal.max-2xlarge:fullscreen | Fullscreen below 2xlarge (1536px) |
Scrollable
By default a modal that is taller than the viewport extends the page and scrolls the entire document. Add .scrollable to lock the .modal-header and .modal-footer in place while only .modal-body scrolls.
<button type="button" class="button primary" data-cx-toggle="dialog" data-cx-target="#scrollableModal">Scrollable body</button>
<dialog class="modal dialog large scrollable max-medium:fullscreen" id="scrollableModal" aria-labelledby="scrollableModalLabel">
<div class="modal-header">
<h2 class="modal-title" id="scrollableModalLabel">Scrollable modal</h2>
<button type="button" class="close-button" data-cx-dismiss="dialog" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>This is some placeholder content to show the scrolling behavior inside a modal body. The header and footer remain fixed while only this area scrolls.</p>
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
<p>This is some more placeholder content at the bottom of the modal body.</p>
</div>
<div class="modal-footer">
<button type="button" class="button neutral" data-cx-dismiss="dialog">Close</button>
</div>
</dialog>Footer layout
The .modal-footer uses flex-direction: row-reverse, so buttons are right-aligned without justify-content — write the primary action first in source, it renders on the right. At the small breakpoint, buttons stretch to equal widths (flex: 1). Add .stacked to stack them as full-width columns instead.
For a third action that should be visually separated — such as a destructive option — add .me-auto (or a responsive variant like .small:me-auto) to push it to the opposite end.
<button type="button" class="button primary" data-cx-toggle="dialog" data-cx-target="#exampleModalFooter">
Open modal
</button>
<dialog class="modal dialog" id="exampleModalFooter" aria-labelledby="exampleModalFooterLabel">
<div class="modal-header">
<h2 class="modal-title" id="exampleModalFooterLabel">Modal with stacked actions</h2>
<button type="button" class="close-button" data-cx-dismiss="dialog" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>A modal with multiple footer actions, stacking full-width at the small breakpoint.</p>
</div>
<div class="modal-footer stacked">
<button type="button" class="button primary">Take action</button>
<button type="button" class="button default" data-cx-dismiss="dialog">Close</button>
<button type="button" class="button danger outline small:me-auto">Destructive</button>
</div>
</dialog>Behaviors
Most behavioral options are off by default — enable each with a data attribute on the <dialog> element or a modifier class.
Animation
Modals animate with an opacity fade combined with a configurable CSS transform. Add .instant to disable all transitions.
The animation is driven by three CSS custom properties. Set them as inline styles for per-instance control, or override the corresponding Sass variables at build time to change the defaults globally (see Sass variables).
| Property | Controls |
|---|---|
--cx-dialog-transition-transform | Entry/exit transform |
--cx-dialog-transition-duration | Transition duration |
--cx-dialog-transition-timing | Easing function |
<!-- Slide from above -->
<dialog class="modal dialog" style="--cx-dialog-transition-transform: translateY(-3rem);" ... >
<!-- Slide from below -->
<dialog class="modal dialog" style="--cx-dialog-transition-transform: translateY(3rem);" ... >
<!-- No animation -->
<dialog class="modal dialog instant" ... >Backdrop
By default clicking the backdrop or pressing Escape closes the modal. data-cx-backdrop="static" blocks closing on backdrop click — the modal scales briefly to indicate it requires explicit action. Add data-cx-keyboard="false" to also block the Escape key.
<dialog class="modal dialog" data-cx-backdrop="static" ... >
<dialog class="modal dialog" data-cx-backdrop="static" data-cx-keyboard="false" ... >Non-modal
The plugin calls showModal() by default, placing the dialog in the top layer and blocking interaction with the page. Set data-cx-modal="false" to open with show() instead — the modal renders at the center of the viewport in the normal stacking context, with no backdrop, and the page behind it remains interactive.
<button type="button" class="button primary" data-cx-toggle="dialog" data-cx-target="#nonmodalDialog" data-cx-modal="false">Open non-modal</button>
<dialog class="modal dialog" id="nonmodalDialog" aria-labelledby="nonmodalLabel">
<div class="modal-header">
<h2 class="modal-title" id="nonmodalLabel">Non-modal dialog</h2>
<button type="button" class="close-button" data-cx-dismiss="dialog" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>The page behind this dialog is still interactive.</p>
</div>
<div class="modal-footer">
<button type="button" class="button neutral" data-cx-dismiss="dialog">Close</button>
</div>
</dialog>Autofocus
When a modal opens, focus moves to the <dialog> element itself rather than the first focusable child. To direct focus to a specific element instead, add the autofocus attribute to it.
<button type="button" class="button primary" data-cx-toggle="dialog" data-cx-target="#autofocusModal">Open modal</button>
<dialog class="modal dialog" id="autofocusModal" aria-labelledby="autofocusModalLabel">
<div class="modal-header">
<h2 class="modal-title" id="autofocusModalLabel">Autofocus modal</h2>
<button type="button" class="close-button" data-cx-dismiss="dialog" aria-label="Close"></button>
</div>
<div class="modal-body">
<input type="text" class="form-input" autofocus placeholder="Receives focus on open" />
</div>
<div class="modal-footer">
<button type="button" class="button neutral" data-cx-dismiss="dialog">Close</button>
</div>
</dialog>Sequential modals
Opening a modal from within an open one performs a seamless dialog swap: the incoming modal opens via showModal() and the outgoing one closes synchronously in the same frame, so the backdrop transitions without a flicker or opacity dip. Add a data-cx-toggle="dialog" trigger inside the open modal and point it at the next dialog.
<button type="button" class="button primary" data-cx-toggle="dialog" data-cx-target="#firstStep">Start process</button>
<!-- First modal -->
<dialog class="modal dialog" id="firstStep" aria-labelledby="firstStepLabel">
<div class="modal-header">
<h2 class="modal-title" id="firstStepLabel">Step 1 of 2</h2>
<button type="button" class="close-button" data-cx-dismiss="dialog" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>The button below opens step 2 as a seamless dialog swap.</p>
</div>
<div class="modal-footer">
<button type="button" class="button primary" data-cx-toggle="dialog" data-cx-target="#secondStep">Continue to step 2</button>
<button type="button" class="button default" data-cx-dismiss="dialog">Close</button>
</div>
</dialog>
<!-- Second modal -->
<dialog class="modal dialog" id="secondStep" aria-labelledby="secondStepLabel">
<div class="modal-header">
<h2 class="modal-title" id="secondStepLabel">Step 2 of 2</h2>
<button type="button" class="close-button" data-cx-dismiss="dialog" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>The backdrop carried over from step 1 without interruption.</p>
</div>
<div class="modal-footer stacked">
<button type="button" class="button primary">Take action</button>
<button type="button" class="button default" data-cx-dismiss="dialog">Close</button>
<button type="button" class="button neutral small:me-auto" data-cx-toggle="dialog" data-cx-target="#firstStep">Back to step 1</button>
</div>
</dialog>Dynamic content
The show.cx.dialog event receives event.relatedTarget — the element that triggered the open — making it straightforward to populate the modal's content based on the trigger.
<button type="button" class="button primary" data-cx-toggle="dialog" data-cx-target="#dynamicModal" data-cx-whatever="@first">First user</button>
<button type="button" class="button primary" data-cx-toggle="dialog" data-cx-target="#dynamicModal" data-cx-whatever="@second">Second user</button>
<button type="button" class="button primary" data-cx-toggle="dialog" data-cx-target="#dynamicModal" data-cx-whatever="@chassis">Chassis</button>
<dialog class="modal dialog" id="dynamicModal" aria-labelledby="dynamicModalLabel">
<div class="modal-header">
<h2 class="modal-title" id="dynamicModalLabel">New message</h2>
<button type="button" class="close-button" data-cx-dismiss="dialog" aria-label="Close"></button>
</div>
<div class="modal-body">
<form>
<div class="mb-medium">
<label for="recipient-name" class="col-form-label">Recipient:</label>
<input type="text" class="form-input" id="recipient-name" />
</div>
<div class="mb-medium">
<label for="message-text" class="col-form-label">Message:</label>
<textarea class="form-input" id="message-text"></textarea>
</div>
<button type="submit" hidden>Submit</button>
</form>
</div>
<div class="modal-footer">
<button type="button" class="button primary">Send message</button>
<button type="button" class="button default" data-cx-dismiss="dialog">Close</button>
</div>
</dialog>// JavaScript to handle dynamic content in the modal
const dynamicModal = document.getElementById('dynamicModal')
if (dynamicModal) {
dynamicModal.addEventListener('show.cx.dialog', event => {
// Button that triggered the modal
const button = event.relatedTarget
// Extract data from data-cx-* attributes
const recipient = button.getAttribute('data-cx-whatever')
// Get the modal elements that need to be updated
const modalTitle = dynamicModal.querySelector('.modal-title')
const recipientInput = dynamicModal.querySelector('#recipient-name')
// Update the modal's content.
modalTitle.textContent = `New message to ${recipient}`
recipientInput.value = recipient
})
}Overlays
Tooltips, popovers, toasts, and menus all work inside modal dialogs and are dismissed automatically when the modal closes. Tooltips and popovers are automatically scoped to the dialog element for top-layer positioning — no extra configuration needed.
<button type="button" class="button primary" data-cx-toggle="dialog" data-cx-target="#interactiveModal">Open modal</button>
<dialog class="modal dialog" id="interactiveModal" aria-labelledby="interactiveModalLabel">
<div class="modal-header">
<h2 class="modal-title" id="interactiveModalLabel">Interactive elements</h2>
<button type="button" class="close-button" data-cx-dismiss="dialog" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>These components work inside modal dialogs.</p>
<div class="d-flex gap-small flex-wrap">
<button type="button" class="button default" data-cx-toggle="tooltip" data-cx-title="Tooltip inside a dialog!">Tooltip</button>
<button type="button" class="button default" data-cx-toggle="popover" data-cx-title="Popover title" data-cx-content="This popover is inside a dialog and renders in the top layer. We include some longer content here to demonstrate the placement and wrapping behavior." data-cx-placement="top">Popover</button>
<button type="button" class="button default" id="dialogToastButton">Show toast</button>
<button class="button default" type="button" data-cx-toggle="menu" aria-expanded="false">Menu</button>
<!-- Menu with nested submenu -->
<div class="menu">
<a class="menu-item" href="#">Action</a>
<a class="menu-item" href="#">Another action</a>
<hr class="menu-divider" />
<div class="submenu">
<button class="menu-item" type="button">More options</button>
<div class="menu">
<a class="menu-item" href="#">Sub-action A</a>
<a class="menu-item" href="#">Sub-action B</a>
<div class="submenu">
<button class="menu-item" type="button">Even more</button>
<div class="menu">
<a class="menu-item" href="#">Deep action 1</a>
<a class="menu-item" href="#">Deep action 2</a>
</div>
</div>
</div>
</div>
</div>
<!-- Menu end -->
</div>
</div>
<div class="modal-footer">
<button type="button" class="button neutral" data-cx-dismiss="dialog">Close</button>
</div>
<!-- Toast container is placed inside the dialog so toasts render above the backdrop and are scoped to the dialog for positioning. -->
<div class="toast-container position-fixed bottom-0 end-0 p-medium">
<div class="toast" id="dialogToast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-body">
Toast inside a dialog!
<div class="mt-small pt-small border-top">
<button type="button" class="button primary small" data-cx-dismiss="toast">Close</button>
</div>
</div>
</div>
</div>
<!-- Toast end -->
</dialog>Accessibility
The <dialog> element carries an implicit role="dialog" when opened with showModal(). Provide an accessible name by placing aria-labelledby on the <dialog> pointing at the .modal-title element's id.
Focus management inside a modal is handled automatically — when the modal opens, focus moves to the <dialog> element itself rather than the first focusable child (typically the close button). Add the autofocus attribute to direct focus to a specific element on open (see Autofocus). For cases where the focus target is determined dynamically, use the shown.cx.dialog event:
document.getElementById('myModal').addEventListener('shown.cx.dialog', () => {
document.getElementById('myInput').focus()
})Body scroll is locked while a modal dialog is open (dialog-open is added to <body>). The lock is released only when all modal dialogs are closed.
JavaScript API
The Dialog plugin opens and closes the <dialog> element and manages the backdrop, body-scroll lock, and transition lifecycle. Chassis JS ships as an ES module — import the Dialog class:
import { Dialog } from '@chassis-ui/css'Triggers
The data-attribute API opens and closes modals without writing any custom JavaScript:
<!-- Trigger button -->
<button data-cx-toggle="dialog" data-cx-target="#myModal">Open modal</button>
<!-- Optional config on the dialog element -->
<dialog class="modal dialog"
data-cx-backdrop="static"
data-cx-keyboard="false">
...
<button data-cx-dismiss="dialog">Close</button>
</dialog>Initialization
For programmatic access — calling methods or listening to events — instantiate each element with the Dialog class:
const dialog = new Dialog('#myModal')
// With options
const dialog = new Dialog('#myModal', {
backdrop: 'static',
keyboard: false
})Options
Options are set via data-cx-* attributes or passed to the constructor as an object. Attribute names use the kebab-case form of the option name — data-cx-custom-class, not data-cx-customClass. Attribute values are parsed to their native types:"true" → true, "0" → 0, and valid JSON strings to objects.
Use data-cx-config to pass multiple options as a JSON string:data-cx-config='{"delay":200}'. Individual data-cx-* attributes take precedence over data-cx-config. You can also use JSON values in individual attributes, such as data-cx-delay='{"show":100,"hide":200}'.
When initializing components, Chassis merges configurations from multiple sources in this priority order: default settings, data-cx-config values, individual data-cx-*attributes, and finally any JavaScript object options. Values defined later in this sequence override earlier ones.
| Option | Type | Default | Description |
|---|---|---|---|
backdrop | boolean | 'static' | true | Show a backdrop. 'static' blocks closing on backdrop click. |
keyboard | boolean | true | Close the modal when Escape is pressed. |
modal | boolean | true | Open via showModal() (top-layer). false uses show() with no backdrop. |
Methods
All Chassis CSS component methods are asynchronous and initiate CSS transitions. Methods return immediately when the transition begins, not when it completes. Calling methods on components that are already transitioning will be ignored to prevent conflicts. Learn more about Chassis JavaScript patterns.
The plugin exposes the following instance methods. show() and hide() return before the transition completes — listen to the shown and hidden events for post-transition timing.
| Method | Description |
|---|---|
show() | Opens the dialog. |
hide() | Closes the dialog. |
toggle() | Toggles open or closed. |
handleUpdate() | No-op. Kept for API compatibility. |
dispose() | Removes the instance and its event listeners. |
getInstance() | Static. Returns the instance for an element, or null. |
getOrCreateInstance() | Static. Returns the existing instance or creates one. |
const dialog = new Dialog('#myModal')
dialog.show()
dialog.hide()
dialog.toggle()
dialog.dispose()
const instance = Dialog.getInstance('#myModal')
const instance = Dialog.getOrCreateInstance('#myModal')Events
All events fire on the <dialog> element. Cancelable events (show.cx.dialog, hide.cx.dialog) can be prevented with event.preventDefault() to block the action.
| Event | Description |
|---|---|
show.cx.dialog | Fires immediately when show() is called. Cancelable. event.relatedTarget is the trigger element. |
shown.cx.dialog | Fires after the entry transition completes and the dialog is fully visible. |
hide.cx.dialog | Fires immediately when hide() is called. Cancelable. |
hidden.cx.dialog | Fires after the exit transition completes and the dialog is fully hidden. |
hidePrevented.cx.dialog | Fires when a close attempt is blocked (static backdrop click, or Escape with keyboard: false). |
cancel.cx.dialog | Fires when the browser's native cancel event fires (Escape on a modal dialog). |
const el = document.getElementById('myModal')
el.addEventListener('show.cx.dialog', event => {
const trigger = event.relatedTarget
const userId = trigger?.getAttribute('data-user-id')
if (userId) loadUserData(userId)
})
el.addEventListener('shown.cx.dialog', () => {
document.getElementById('myInput').focus()
})
el.addEventListener('hidden.cx.dialog', () => {
el.querySelector('form')?.reset()
})CSS
The Modal component can be customized through Sass variables at compile time.
Custom properties
The Modal component exposes CSS custom properties to control its appearance at runtime.
The --dialog-* properties control animation timing and the backdrop. The --modal-* properties control visual style. Both sets are scoped to the <dialog> element and can be overridden per-instance.
--cx-dialog-transition-transform: scale(1.05);
--cx-dialog-transition-duration: 0.3s;
--cx-dialog-transition-timing: cubic-bezier(0.22, 1, 0.36, 1);
--cx-dialog-backdrop-bg: var(--cx-black-dim-main);
--cx-dialog-backdrop-blur: 8px;
--cx-dialog-margin: 2rem;--cx-zindex: var(--cx-modal-zindex, 1050);
--cx-width: var(--cx-modal-width, 35rem);
--cx-fg-color: var(--cx-modal-fg-color, var(--cx-fg-main));
--cx-bg-color: var(--cx-modal-bg-color, var(--cx-bg-main));
--cx-border-color: var(--cx-modal-border-color, var(--cx-border-subtle));
--cx-border-width: var(--cx-modal-border-width, var(--cx-border-width-medium));
--cx-border-radius: var(--cx-modal-border-radius, var(--cx-border-radius-xlarge));
--cx-padding-y: var(--cx-modal-padding-y, 1rem);
--cx-padding-x: var(--cx-modal-padding-x, 1rem);
--cx-gap: var(--cx-modal-gap, 1rem);
--cx-box-shadow: var(--cx-modal-box-shadow, var(--cx-box-shadow-large));
--cx-title-font-family: var(--cx-modal-title-font-family, var(--cx-font-family-text));
--cx-title-font-size: var(--cx-modal-title-font-size, var(--cx-font-size-large));
--cx-title-font-weight: var(--cx-modal-title-font-weight, var(--cx-font-weight-strong));
--cx-title-line-height: var(--cx-modal-title-line-height, var(--cx-line-height-large));
--cx-footer-large-gap: var(--cx-modal-footer-large-gap, var(--cx-space-medium));
--cx-footer-small-gap: var(--cx-modal-footer-small-gap, var(--cx-space-small));
--cx-close-button-size: var(--cx-modal-close-button-size, var(--cx-icon-medium));/* Override animation timing for a single modal */
#myModal {
--dialog-transition-duration: .5s;
--dialog-transition-timing: ease-in-out;
}
/* Override backdrop appearance */
#myModal {
--dialog-backdrop-bg: rgb(0 0 0 / 70%);
--dialog-backdrop-blur: 4px;
}Sass variables
The Modal component uses Sass variables in scss/config/_defaults.scss to define its defaults.
$dialog-margin: 2rem;
$dialog-margin-small: 1rem; // Margin applied on smaller viewports (e.g. mobile).
$dialog-backdrop-bg: var(--black-dim-main);
$dialog-backdrop-blur: 8px;
$dialog-transition-transform: scale(1.05);
$dialog-transition-duration: .3s;
$dialog-transition-timing: cubic-bezier(.22, 1, .36, 1);$modal-fg-color: var(--fg-main);
$modal-bg-color: var(--bg-main);
$modal-border-color: var(--border-subtle);
$modal-border-width: var(--border-width-medium);
$modal-border-radius: var(--border-radius-xlarge);
$modal-footer-large-gap: var(--space-medium);
$modal-footer-small-gap: var(--space-small);
$modal-close-button-size: var(--icon-medium);Design tokens
The Modal component consumes design tokens from Chassis Tokens with the $cx- prefix. — See thedesign tokens page.
$modal-xlarge-width: $cx-size-modal-window-xlarge-w;
$modal-large-width: $cx-size-modal-window-large-w;
$modal-medium-width: $cx-size-modal-window-medium-w;
$modal-small-width: $cx-size-modal-window-small-w;
$modal-large-padding-y: $cx-space-modal-large-padding-y;
$modal-large-padding-x: $cx-space-modal-large-padding-x;
$modal-large-gap: $cx-space-modal-large-gap;
$modal-medium-padding-y: $cx-space-modal-medium-padding-y;
$modal-medium-padding-x: $cx-space-modal-medium-padding-x;
$modal-medium-gap: $cx-space-modal-medium-gap;
$modal-small-padding-y: $cx-space-modal-small-padding-y;
$modal-small-padding-x: $cx-space-modal-small-padding-x;
$modal-small-gap: $cx-space-modal-small-gap;
$modal-medium-title-font: $cx-font-modal-medium-title;
$modal-small-title-font: $cx-font-modal-small-title;
$modal-box-shadow: $cx-shadow-modal-main;