Skip to content
GitHub

Dialog

Dialog Title

Your dialog content here.

OK

The dialog component is built on the native HTML <dialog> element, providing excellent browser support and accessibility features. It supports both modal and non-modal modes, with full keyboard navigation and screen reader support.

To use the dialog component, include the following HTML in your page:

<fulcrum-element-dialog
  id="dialog2"
  aria-labelledby="dialog-title"
  aria-describedby="dialog-description"
  cloak
>
  <div class="dialog-content">
    <h2 id="dialog-title">Dialog Title</h2>
    <p id="dialog-description">Your dialog content here.</p>
    <fulcrum-element-dialog-close aria-label="Close this dialog"
      >OK</fulcrum-element-dialog-close
    >
  </div>
</fulcrum-element-dialog>

The dialog content is completely under your control. You can include any HTML structure inside the dialog element. For accessibility, we recommend using proper heading structure and labeling the dialog appropriately.

Use JavaScript to control the dialog:

const dialog = document.querySelector("fulcrum-element-dialog");

// Open the dialog
dialog.open();

// Close the dialog
dialog.close();

// Force close (bypasses cancel events)
dialog.forceClose();

You can also use the open attribute to control the dialog state:

<fulcrum-element-dialog open>
  <!-- Dialog content -->
</fulcrum-element-dialog>

The dialog component supports the following attributes:

  • modal: Controls whether the dialog is modal (blocks interaction with the page) or non-modal. Default: true
  • open: Controls the open/closed state of the dialog. Default: false
  • cloak: Initially hides the dialog to prevent flash of unstyled content during initialization. Default: false
  • show-close: Shows or hides the built-in close button. Default: true
  • position: Controls dialog positioning. Options: default, top-left, top-center, top-right, center-left, center-right, bottom-left, bottom-center, bottom-right. Default: default
  • shadow: Controls dialog shadow depth. Options: high, medium, low, none. Default: medium
  • aria-label: Provides an accessible label for the dialog
  • aria-labelledby: References the ID of an element that labels the dialog
  • aria-describedby: References the ID of an element that describes the dialog
<!-- Modal dialog (default) -->
<fulcrum-element-dialog modal>
  <!-- Blocks interaction with page -->
</fulcrum-element-dialog>

<!-- Non-modal dialog -->
<fulcrum-element-dialog modal="false">
  <!-- Page remains interactive -->
</fulcrum-element-dialog>

Control where the dialog appears on screen:

<!-- Top row positions -->
<fulcrum-element-dialog position="top-left">
  <h2>Top Left Dialog</h2>
</fulcrum-element-dialog>

<fulcrum-element-dialog position="top-center">
  <h2>Top Center Dialog</h2>
</fulcrum-element-dialog>

<fulcrum-element-dialog position="top-right">
  <h2>Top Right Dialog</h2>
</fulcrum-element-dialog>

<!-- Middle row positions -->
<fulcrum-element-dialog position="center-left">
  <h2>Center Left Dialog</h2>
</fulcrum-element-dialog>

<fulcrum-element-dialog position="default">
  <h2>Centered Dialog</h2>
</fulcrum-element-dialog>

<fulcrum-element-dialog position="center-right">
  <h2>Center Right Dialog</h2>
</fulcrum-element-dialog>

<!-- Bottom row positions -->
<fulcrum-element-dialog position="bottom-left">
  <h2>Bottom Left Dialog</h2>
</fulcrum-element-dialog>

<fulcrum-element-dialog position="bottom-center">
  <h2>Bottom Center Dialog</h2>
</fulcrum-element-dialog>

<fulcrum-element-dialog position="bottom-right">
  <h2>Bottom Right Dialog</h2>
</fulcrum-element-dialog>

Control the dialog’s shadow for visual hierarchy:

<!-- High shadow (most prominent) -->
<fulcrum-element-dialog shadow="high">
  <h2>High Shadow Dialog</h2>
</fulcrum-element-dialog>

<!-- Medium shadow (default) -->
<fulcrum-element-dialog shadow="medium">
  <h2>Medium Shadow Dialog</h2>
</fulcrum-element-dialog>

<!-- Low shadow (subtle) -->
<fulcrum-element-dialog shadow="low">
  <h2>Low Shadow Dialog</h2>
</fulcrum-element-dialog>

<!-- No shadow -->
<fulcrum-element-dialog shadow="none">
  <h2>No Shadow Dialog</h2>
</fulcrum-element-dialog>

You can easily customize the dialog size using CSS custom properties:

/* Set dialog size for all dialogs */
fulcrum-element-dialog {
  --dialog-width: 600px; /* Dialog width */
  --dialog-height: 400px; /* Dialog height */
  --dialog-max-width: 90vw; /* Maximum width */
  --dialog-max-height: 80vh; /* Maximum height */
  --dialog-padding: 2rem; /* Content padding */
  --dialog-border-radius: 12px; /* Border radius */
}

/* Or target specific dialogs */
#large-dialog {
  --dialog-width: 800px;
  --dialog-height: 600px;
}

#small-dialog {
  --dialog-width: 400px;
  --dialog-max-height: 50vh;
}
  • --dialog-width: Dialog width (default: min(90vw, 500px))
  • --dialog-height: Dialog height (default: auto)
  • --dialog-min-width: Minimum width (default: 320px)
  • --dialog-min-height: Minimum height (default: auto)
  • --dialog-max-width: Maximum width (default: min(calc(100vw - 2rem), 800px))
  • --dialog-max-height: Maximum height (default: calc(100vh - 2rem))
  • --dialog-padding: Content padding (default: 1.5rem)
  • --dialog-border-radius: Border radius (default: 8px)

The dialog includes a built-in close button (<fulcrum-element-dialog-close>) in the upper-right corner that automatically closes the parent dialog. You can customize or replace it entirely.

<!-- Close button is shown by default -->
<fulcrum-element-dialog>
  <h2>Dialog with close button</h2>
  <p>The X button will appear in the top-right corner.</p>
</fulcrum-element-dialog>

<!-- Hide the default close button -->
<fulcrum-element-dialog show-close="false">
  <h2>Dialog without close button</h2>
  <p>No close button will be shown.</p>
  <button onclick="this.closest('fulcrum-element-dialog').close()">
    Custom Close
  </button>
</fulcrum-element-dialog>

You can also use the <fulcrum-element-dialog-close> component anywhere in your dialog content:

<fulcrum-element-dialog show-close="false">
  <h2>Dialog Title</h2>
  <p>Dialog content here.</p>

  <!-- Custom positioned close button -->
  <fulcrum-element-dialog-close aria-label="Close this dialog">
    <span>✕ Close</span>
  </fulcrum-element-dialog-close>

  <!-- Or multiple close buttons -->
  <div class="dialog-actions">
    <button>Save</button>
    <fulcrum-element-dialog-close>
      <span>Cancel</span>
    </fulcrum-element-dialog-close>
  </div>
</fulcrum-element-dialog>

Customize the close button appearance with CSS custom properties:

fulcrum-element-dialog-close {
  --dialog-close-size: 2.5rem; /* Button size */
  --dialog-close-top: 1rem; /* Top position */
  --dialog-close-right: 1rem; /* Right position */
  --dialog-close-background: transparent; /* Background color */
  --dialog-close-color: #666; /* Icon/text color */
  --dialog-close-hover-background: #f0f0f0; /* Hover background */
  --dialog-close-hover-color: #000; /* Hover color */
  --dialog-close-border-radius: 50%; /* Border radius */
  --dialog-close-icon-size: 1.2rem; /* Icon size */
  --dialog-close-icon-stroke: 2; /* Icon stroke width */
}

The <fulcrum-element-dialog-close> component supports these attributes:

  • disabled: Disables the close button and prevents interaction. Default: false
  • Automatically handles keyboard navigation (Enter and Space keys)
  • Includes proper ARIA roles and tabindex management

Fired when the dialog opens:

const dialog = document.querySelector("fulcrum-element-dialog");
dialog.addEventListener("dialog-open", (event) => {
  console.log("Dialog opened:", event.detail.dialog);
});

Fired when the dialog closes:

const dialog = document.querySelector("fulcrum-element-dialog");
dialog.addEventListener("dialog-close", (event) => {
  console.log("Dialog closed:", event.detail.dialog);
});

Fired when the user attempts to cancel the dialog (e.g., pressing Escape). This event is cancelable:

const dialog = document.querySelector("fulcrum-element-dialog");
dialog.addEventListener("dialog-cancel", (event) => {
  // Prevent the dialog from closing
  event.preventDefault();
  console.log("Dialog cancel prevented");
});

The dialog component is built with accessibility as a priority:

  • Screen Reader Support: Proper ARIA attributes and roles
  • Keyboard Navigation:
    • Escape key closes the dialog (unless prevented)
    • Focus is trapped within modal dialogs
    • Focus returns to the trigger element when closed
  • ARIA Properties: Support for aria-label, aria-labelledby, and aria-describedby
  • High Contrast: Proper borders and contrast in high contrast mode
  • Reduced Motion: Respects prefers-reduced-motion setting
  1. Always provide a label using aria-label or aria-labelledby
  2. Use proper heading structure within the dialog
  3. Ensure interactive elements are focusable
  4. Test with keyboard navigation and screen readers
<!-- Good accessibility example -->
<fulcrum-element-dialog
  aria-labelledby="dialog-title"
  aria-describedby="dialog-description"
>
  <h2 id="dialog-title">Confirmation</h2>
  <p id="dialog-description">Are you sure you want to delete this item?</p>
  <div>
    <button type="button" onclick="deleteItem()">Delete</button>
    <button
      type="button"
      onclick="this.closest('fulcrum-element-dialog').close()"
    >
      Cancel
    </button>
  </div>
</fulcrum-element-dialog>

The dialog component is built on the native <dialog> element, which has excellent modern browser support. It gracefully handles older browsers through polyfill behavior.

The dialog component is built with minimal dependencies:

  • Native HTML <dialog> element
  • Lit for web component functionality
  • CSS custom properties for theming