Overlays

Layers above the page

Overlays interrupt. Use them only when the task needs focus or context the page can't give, and always make the way out obvious.

OverlayUseDismiss
Dialog (modal)A decision that blocks: confirm destructive actions, unsaved changes, short focused formsButtons, Esc; scrim click only if nothing would be lost
DrawerDetail or editing alongside a list: user details, filters, Mai docked panelClose button, Esc, scrim
Bottom sheetMobile equivalent of drawers and menusSwipe down, scrim, close button
PopoverRich help or a small form anchored to a controlOutside click, Esc
MenuA list of actions or optionsSelection, outside click, Esc
TooltipName or short hint for a controlMoving away, Esc

Dialogs

Short, specific, safe

  • Title asks the question or names the task: “Revoke licence for Noura Obaid?”
  • Body says the consequence in one or two sentences.
  • Buttons repeat the action (“Revoke licence”), not “OK”; the safe option is the secondary button; the destructive one is danger and last.
  • Width 480px (640px for forms), 24px radius, shadow 4, on a Midnight scrim with 4px backdrop blur.
  • Focus moves into the dialog, is trapped there, and returns to the trigger on close. Use the native <dialog> element.
  • Never stack dialogs. Never open a dialog without a user action.

Delete “Water security outlook 2030”?

The analysis, its 14 sources and all Artifacts will be deleted for everyone.

Drawers and bottom sheets

Context without leaving the page

  • From the trailing edge (right; left in RTL), 380–480px wide, full height, shadow 4, with a scrim on narrow screens.
  • Header with title and close button; footer with actions when editing.
  • On mobile, drawers become bottom sheets with a handle and a maximum of 90% height.
  • Mai's docked panel is a non-modal drawer: no scrim, the page stays usable.
Sara Khalil
Organisation
Ministry of Water
Modules
All
Status
Expiring

Controls over images

Zoom, download, captions

  • Overlay buttons sit in the top-right corner (top-left in RTL) with a 12px inset, in a row with 8px gaps: zoom first, then download, then more.
  • They use the floating icon button: translucent Midnight 95 at 64%, Snow icon, 8px backdrop blur, 40px (32px in dense galleries).
  • Visible on hover and keyboard focus on desktop; always visible on touch and when the image is the main content.
  • Badges (status, “AI-generated”) go top-left. Captions go along the bottom on a Midnight gradient, Snow text 13px.
  • Zoom opens a full-screen viewer on a 92% Midnight 95 backdrop with close (top right), arrows for galleries, pinch and Esc.
Shaheen illustrationIllustration
Shaheen: strategy with a human in the loop

Hover or focus the image.

Controls over code and text

  • Copy buttons on code blocks: top right inside the block header, always visible when there is a header; floating (top right, 10px inset, on hover/focus) when there isn't.
  • Copy buttons on single values: an inline icon button right after the value.
  • “Expand” on long code or text: a full-width “Show all 84 lines” button at the bottom of a faded block.
  • Never cover the first line of content with a control: reserve the header row or the right gutter.

Placement rules

ElementAnchored toOffsetCollision
Menu, dropdownTrigger, start-aligned below6pxFlip above; shift inside viewport
PopoverTrigger, centred below8px, with arrowFlip to the side with most space
TooltipElement, centred above8px, with arrowFlip below
Toast stackViewport bottom-right (bottom-left RTL; bottom-centre on mobile)24pxStack upwards, max 3
Image overlay buttonsImage top-right (top-left RTL)12px—
Copy buttonCode block top-right10px—

Code

<dialog class="n-dialog" aria-labelledby="t">
  <h3 id="t">Revoke licence?</h3>
  <p>…</p>
  <div class="n-dialog__actions"><button class="n-btn n-btn--secondary">Cancel</button><button class="n-btn n-btn--danger">Revoke licence</button></div>
</dialog>
dialog::backdrop { background: var(--n-scrim); backdrop-filter: blur(var(--n-filter-blur-scrim)); }

<figure class="n-media"><img …><span class="n-media__actions"><button class="n-icon-btn n-icon-btn--float" aria-label="Zoom in">…</button></span></figure>

Dos and don'ts

Do

  • Use native dialog and return focus on close.
  • Put overlay controls top right with a 12px inset.
  • Name the action in the dialog button.
  • Use bottom sheets on mobile.

Don't

  • Open dialogs on page load.
  • Stack overlays on overlays.
  • Cover content with permanently visible controls.
  • Use a dialog where an inline message would do.

Last updated on 14 October 2026