Starting Point
v0.25.0
Start typing to search...
Go to Page
escClose

Dialog

The dialog opens a modal window above the page and blocks interaction with everything behind it. Use it for confirmations, short forms, and alerts that need a decision; for a panel that slides in from the edge, reach for the sheet.

<button id="dialog-1-trigger" class="btn btn-outline">Open Dialog</button>
 
<dialog class="dialog" data-sp-toggle="#dialog-1-trigger">
  <form class="dialog-panel">
    <button
      type="button"
      class="btn btn-ghost btn-xs btn-icon absolute top-3 right-3"
      aria-label="Close"
      data-sp-dismiss
    >
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
    </button>
    <div class="dialog-header">
      <h2 class="dialog-title">Edit profile</h2>
      <p class="dialog-description">
        Make changes to your profile here. Click save when you're done.
      </p>
    </div>
    <div class="dialog-content">
      <div class="field-group">
        <div class="field">
          <label class="label" for="dialog-profile-name">Name</label>
          <input
            class="input"
            id="dialog-profile-name"
            name="name"
            value="Pedro Duarte"
          />
        </div>
        <div class="field">
          <label class="label" for="dialog-profile-username">Username</label>
          <input
            class="input"
            id="dialog-profile-username"
            name="username"
            value="@peduarte"
          />
        </div>
      </div>
    </div>
    <div class="dialog-footer">
      <button type="button" class="btn btn-outline" data-sp-dismiss>
        Cancel
      </button>
      <button type="submit" class="btn">Save changes</button>
    </div>
  </form>
</dialog>

Usage

Add the dialog class to a <dialog> element. Give your trigger an id, then point the dialog at it with data-sp-toggle. The trigger can be any element. Close the dialog with data-sp-dismiss on a button, a backdrop click, or the Escape key.

ClassDescription
dialogAdd to the <dialog> element; fills the viewport and dims the page
dialog-panelAdd to the child element that is the visible panel
dialog-headerAdd to the block holding the title and description
dialog-titleAdd to a heading element to create the dialog title
dialog-descriptionAdd to a paragraph to create the supporting description
dialog-contentAdd to the body section between header and footer
dialog-footerAdd to the action row at the bottom of the panel
<!-- This is a button toggling the dialog -->
<button id="my-trigger" class="btn btn-outline">Open Dialog</button>
 
<!-- This is the dialog -->
<dialog class="dialog" data-sp-toggle="#my-trigger">
  <div class="dialog-panel">
    <div class="dialog-header">
      <h2 class="dialog-title">Title</h2>
      <p class="dialog-description">Description</p>
    </div>
    <div class="dialog-footer">
      <button class="btn btn-outline" data-sp-dismiss>Close</button>
    </div>
  </div>
</dialog>

Examples

Custom close button

Any element with data-sp-dismiss closes the dialog, so put close buttons wherever the layout needs them.

<button id="dialog-share-trigger" class="btn btn-outline">Share</button>
 
<dialog class="dialog" data-sp-toggle="#dialog-share-trigger">
  <div class="dialog-panel">
    <button
      class="btn btn-ghost btn-xs btn-icon absolute top-3 right-3"
      aria-label="Close"
      data-sp-dismiss
    >
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
    </button>
    <div class="dialog-header">
      <h2 class="dialog-title">Share link</h2>
      <p class="dialog-description">
        Anyone who has this link will be able to view this.
      </p>
    </div>
    <div class="dialog-content">
      <div class="field">
        <label class="label sr-only" for="dialog-share-link">Link</label>
        <input
          class="input"
          id="dialog-share-link"
          value="https://startingpointui.com/guides/installation"
          readonly
        />
      </div>
    </div>
    <div class="dialog-footer sm:justify-start">
      <button class="btn" data-sp-dismiss>Close</button>
    </div>
  </div>
</dialog>

Cap the body's height and let it scroll on its own: the header and footer stay pinned while the content scrolls between them.

<button id="dialog-sticky-trigger" class="btn btn-outline">
  Sticky Footer
</button>
 
<dialog class="dialog" data-sp-toggle="#dialog-sticky-trigger">
  <div class="dialog-panel">
    <button
      class="btn btn-ghost btn-xs btn-icon absolute top-3 right-3"
      aria-label="Close"
      data-sp-dismiss
    >
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
    </button>
    <div class="dialog-header">
      <h2 class="dialog-title">Sticky Footer</h2>
      <p class="dialog-description">
        This dialog has a sticky footer that stays visible while the content
        scrolls.
      </p>
    </div>
    <div
      class="dialog-content scrollbar-none max-h-[50vh] overflow-y-auto leading-normal"
    >
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod
        tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
        veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
        commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
        velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
        occaecat cupidatat non proident, sunt in culpa qui officia deserunt
        mollit anim id est laborum.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod
        tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
        veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
        commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
        velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
        occaecat cupidatat non proident, sunt in culpa qui officia deserunt
        mollit anim id est laborum.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod
        tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
        veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
        commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
        velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
        occaecat cupidatat non proident, sunt in culpa qui officia deserunt
        mollit anim id est laborum.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod
        tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
        veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
        commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
        velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
        occaecat cupidatat non proident, sunt in culpa qui officia deserunt
        mollit anim id est laborum.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod
        tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
        veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
        commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
        velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
        occaecat cupidatat non proident, sunt in culpa qui officia deserunt
        mollit anim id est laborum.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod
        tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
        veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
        commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
        velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
        occaecat cupidatat non proident, sunt in culpa qui officia deserunt
        mollit anim id est laborum.
      </p>
    </div>
    <div class="dialog-footer">
      <button class="btn btn-outline" data-sp-dismiss>Close</button>
    </div>
  </div>
</dialog>

Scrollable content

The same scrolling body without a footer.

<button id="dialog-scroll-trigger" class="btn btn-outline">
  Scrollable Content
</button>
 
<dialog class="dialog" data-sp-toggle="#dialog-scroll-trigger">
  <div class="dialog-panel">
    <button
      class="btn btn-ghost btn-xs btn-icon absolute top-3 right-3"
      aria-label="Close"
      data-sp-dismiss
    >
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
    </button>
    <div class="dialog-header">
      <h2 class="dialog-title">Scrollable Content</h2>
      <p class="dialog-description">
        This is a dialog with scrollable content.
      </p>
    </div>
    <div
      class="dialog-content scrollbar-none max-h-[50vh] overflow-y-auto leading-normal"
    >
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod
        tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
        veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
        commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
        velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
        occaecat cupidatat non proident, sunt in culpa qui officia deserunt
        mollit anim id est laborum.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod
        tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
        veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
        commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
        velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
        occaecat cupidatat non proident, sunt in culpa qui officia deserunt
        mollit anim id est laborum.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod
        tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
        veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
        commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
        velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
        occaecat cupidatat non proident, sunt in culpa qui officia deserunt
        mollit anim id est laborum.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod
        tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
        veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
        commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
        velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
        occaecat cupidatat non proident, sunt in culpa qui officia deserunt
        mollit anim id est laborum.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod
        tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
        veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
        commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
        velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
        occaecat cupidatat non proident, sunt in culpa qui officia deserunt
        mollit anim id est laborum.
      </p>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod
        tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
        veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
        commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
        velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
        occaecat cupidatat non proident, sunt in culpa qui officia deserunt
        mollit anim id est laborum.
      </p>
    </div>
  </div>
</dialog>

Alert dialog

An alert dialog interrupts the user and requires a choice. Add data-sp-static so a backdrop click won't dismiss it (Escape still closes, so keyboard users are never stuck) and author role="alertdialog" on the element. Put autofocus on the least destructive action and skip the close button.

<button id="alert-trigger" class="btn btn-outline">Show Dialog</button>
 
<dialog
  class="dialog"
  role="alertdialog"
  data-sp-toggle="#alert-trigger"
  data-sp-static
>
  <div class="dialog-panel">
    <div class="dialog-header">
      <h2 class="dialog-title">Are you absolutely sure?</h2>
      <p class="dialog-description">
        This will permanently delete your account and remove your data from our
        servers.
      </p>
    </div>
    <div class="dialog-footer">
      <button class="btn btn-outline" data-sp-dismiss autofocus>Cancel</button>
      <button class="btn" data-sp-dismiss>Continue</button>
    </div>
  </div>
</dialog>

CSS variables

The panel's spacing rhythm is one component-local variable: the panel derives its vertical padding and section gap from it, and each section its horizontal padding. Override it per instance with an arbitrary property, or for the whole app with a plain CSS rule.

VariableDefaultDescription
--dialog-spacing1.5remPadding and gap rhythm of the panel and its sections
<div class="dialog-panel [--dialog-spacing:--spacing(4)]"></div>

Options

Dialog

Set each option with its own data-sp-* attribute on the dialog element.

AttributeValuesDefault
data-sp-toggleCSS selector—
data-sp-staticBooleanfalse
<dialog class="dialog" data-sp-toggle="#my-trigger" data-sp-static></dialog>

JavaScript

Events

Lifecycle events fire on the dialog element; before* events are cancelable.

EventWhen
sp-beforeshowBefore showing (cancelable)
sp-showOpening
sp-shownOpen and settled
sp-beforehideBefore hiding (cancelable)
sp-hideClosing
sp-hiddenClosed
sp-hidepreventedA static dialog refused a backdrop dismiss
el.addEventListener("sp-beforeshow", (e) => {
  if (!ready) e.preventDefault(); // veto the open
});

Methods

Get the instance with sp.dialog(el), then call its methods:

MethodDescription
show()Open the dialog
hide()Close the dialog
toggle()Open if closed, else close
const dialog = sp.dialog(document.querySelector("#my-dialog"));
 
dialog.show();