mica

Example

Confirm

This is a description.

Body content sits between header and footer.

Drawer

The same native dialog dressed as a drawer.

Body content; the footer pins to the bottom with stacked actions.

Basic usage

<button commandfor="confirm" command="show-modal">Open</button>  <!-- trigger -->

<dialog id="confirm">          <!-- content -->
  <button class="close" commandfor="confirm" command="close" aria-label="Close">&#x2715;</button>
  <header>                     <!-- header -->
    <h2>Are you sure?</h2>     <!-- title -->
    <p>This cannot be undone.</p>  <!-- description -->
  </header>

  <p>Any body content.</p>

  <footer>                     <!-- footer: right-aligned row -->
    <form method="dialog">
      <button>Cancel</button>
      <button data-variant="primary" value="ok">Confirm</button>
    </form>
  </footer>
</dialog>

API

Attributes

NameTypeDefaultDescription
data-drawerbooleanfalseTurns the dialog into a responsive desktop side sheet and mobile bottom sheet.
opennative booleanfalseReflects whether the native dialog is open. Prefer showModal() to open a modal.

Content/markup contract

PartContractDefaultDescription
headerdirect childoptionalContains the title and description.
Bodyone element between header and footerPadded, scrollable content region.
footerdirect childoptionalRight-aligned actions; drawer actions stack and pin to the bottom. A form method="dialog" closes natively.
button.closedirect childoptionalCorner dismiss control; provide an accessible name.

Native methods and values

NameTypeDefaultDescription
showModal()methodOpens in the top layer with modal focus and backdrop behavior.
close()methodCloses the dialog.
returnValuestring property""Carries the value of the button that submitted a method="dialog" form.

drawer.js

Optional. Below 40rem the drawer is a content-height, full-width bottom sheet. The module adds a grab handle and swipe-to-dismiss from the handle/header strip: downward drags follow the pointer, upward drags resist, and the sheet closes past one third of its height or on a flick. It also manages the mobile scrim, lightening it during drag and fading it on close, including on iOS. Without the module, open/close, Esc, and the CSS-only scrim still work; no handle appears.

<script type="module" src="mica/drawer.js"></script>

On mobile the handle is the dismiss affordance, so you may hide the redundant corner close button:

@media (max-width: 40rem) {
  dialog[data-drawer] > button.close { display: none; }
}

invoker.js

Temporary optional shim for the recipe's show-modal and close invoker commands. It installs nothing when commands are native.

<script type="module" src="mica/invoker.js"></script>

Accessibility

Native modal dialogs provide top-layer behavior, focus trapping, Esc dismissal, and backdrop handling. Give icon-only close buttons an accessible name. Use a heading and description in the header so the purpose is clear.

Browser support

Invoker commands (commandfor/command) are Baseline newly-available (Chrome 135+, Firefox 144+, Safari 26.2+). Include invoker.js until they are widely available. The shim's removal is a one-line diff.

Notes

Enter/exit animations use @starting-style and transition-behavior: allow-discrete. Standard modal backdrops fade where the engine supports top-layer exit transitions.

← stepperaccordion →