Modal

Raw
GuidancelatestCarbon v11Retrieved 2026-05-12

Carbon Design System — Modal

Overview

Modals focus user attention on a single task or message by placing content over the main UI with a blocking overlay. Use for confirmations, forms requiring separate context, or critical alerts. Avoid modals for simple messages that could be inline or toasted.

Carbon Modal corresponds to the web ARIA pattern role="dialog".


Variants

Passive modal

  • No action buttons in the footer
  • Used for informational content; dismissed by close icon or Esc key
  • Example: "Your session will expire in 5 minutes"

Transactional modal

  • Has primary + secondary buttons in footer
  • Not dismissible by clicking outside (by default) — user must take an action
  • Used for: form submission, confirming a choice, save/discard prompts

Danger modal

  • Same as transactional, but the primary action button uses danger kind
  • Use for irreversible destructive actions: delete account, purge data, disconnect service
  • Red danger button (right) + cancel button (left)

Acknowledgment modal

  • Single button only (typically "OK" or "Got it")
  • Used when the user must acknowledge something before continuing

Sizes

SizeMax-width
xs448px
sm592px
md (default)768px
lg1024px

Choose based on content volume. Forms typically use sm or md; detailed reference content may use lg.


Anatomy

ModalHeader

<ModalHeader label="Optional context" title="Modal heading" />
  • Label (optional) — small text above the heading; provides context (e.g., "Account settings")
  • Title — main heading; concise and action-oriented
  • Close buttonX icon in top-right corner; always present

ModalBody

<ModalBody hasForm hasScrollingContent>
  {/* content */}
</ModalBody>
  • hasForm — removes default padding so form elements align correctly
  • hasScrollingContent — adds a fade gradient at the bottom to indicate overflow

ModalFooter

<ModalFooter
  primaryButtonText="Save"
  secondaryButtonText="Cancel"
  onRequestSubmit={handleSave}
  onRequestClose={handleClose}
/>
  • Secondary (cancel) button on the left
  • Primary (confirm) button on the right
  • Danger modal: use danger prop on Modal (automatically styles primary button as danger)

Focus management

On open, focus moves to the first interactive element inside the modal. If a specific element should receive focus, add data-modal-primary-focus to it, or use the selectorPrimaryFocus prop.

<Modal selectorPrimaryFocus="[data-modal-primary-focus]">
  <ModalBody>
    <TextInput data-modal-primary-focus labelText="Name" />
  </ModalBody>
</Modal>

Tab cycling stays within the modal — focus does not escape to the page behind.


Behavior

<Modal
  open={isOpen}
  onRequestClose={handleClose}
  onRequestSubmit={handleSubmit}
  preventCloseOnClickOutside  /* for transactional modals */
  modalHeading="Delete workspace"
  danger
>
  <ModalBody>
    <p>This action cannot be undone.</p>
  </ModalBody>
  <ModalFooter
    primaryButtonText="Delete"
    secondaryButtonText="Cancel"
  />
</Modal>
  • open controls visibility
  • preventCloseOnClickOutside — set for transactional/danger modals; users must interact with the buttons
  • onRequestClose fires on close icon click, Esc key, or (if enabled) outside click
  • Modal renders into a portal at the document body — no z-index conflicts

Floating menus inside modals

If the modal contains dropdowns, date pickers, or tooltips, pass their selector to selectorsFloatingMenus so they don't trap focus incorrectly:

<Modal selectorsFloatingMenus=".cds--date-picker__calendar">

Accessibility

  • role="dialog", aria-modal="true"
  • aria-labelledby pointing to ModalHeader title
  • Focus trap: keyboard navigation stays within modal bounds
  • Return focus to trigger element on close
  • Esc key closes passive modals; for transactional, Esc fires onRequestClose (which may be a no-op)
  • Screen reader announcement: modal heading is read when dialog opens