Best for
- Use when designing dialogs, confirmation prompts, side panels, action sheets, or any UI element that appears above the main content layer.
dembrandt/dembrandt-skills/skills/modal-and-overlay-patterns/SKILL.md
Overlays — modals, drawers, bottom sheets, popovers — interrupt or augment the main flow. Each type has a different scope, blocking level, and appropriate use case. Use when designing dialogs, confirmation prompts, side panels, action sheets, or any UI element that appears above the main content layer.
Decision brief
Overlays appear above the main content layer. They range from lightweight popovers (non-blocking, anchored to a trigger) to full blocking modals (require a user response before the app continues). Choosing the right overlay type for the task prevents unnecessary interruption and…
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/dembrandt/dembrandt-skills --skill "skills/modal-and-overlay-patterns"Inspect the Agent Skill "modal-and-overlay-patterns" from https://github.com/dembrandt/dembrandt-skills/blob/643a0b75f2bacc2d77dd6bae07601ab40128bb12/skills/modal-and-overlay-patterns/SKILL.md at commit 643a0b75f2bacc2d77dd6bae07601ab40128bb12. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
Use a focus trap library or the native element, which handles trapping natively in modern browsers. Rolling a manual focus trap is error-prone.
[ ] Is the correct overlay type chosen for the task (tooltip / popover / menu / bottom sheet / drawer / modal)?
Choose the lightest type that satisfies the task. Heavier overlays carry higher cognitive cost.
A tooltip appears on hover or keyboard focus and disappears when the trigger loses focus. It is purely informational — no interactive elements inside.
A popover is anchored to a trigger but contains interactive content — a colour picker, a date range selector, a small form, a list of filters. Unlike a tooltip, it stays open while the user interacts.
Permission review
No configured static risk pattern was detected
This is not proof of safety. Runtime behavior, indirect dependencies, and hidden external systems are outside the static scan.
Evidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 95/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 47 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Overlays appear above the main content layer. They range from lightweight popovers (non-blocking, anchored to a trigger) to full blocking modals (require a user response before the app continues). Choosing the right overlay type for the task prevents unnecessary interruption and keeps the user oriented.
Choose the lightest type that satisfies the task. Heavier overlays carry higher cognitive cost.
| Type | Blocks background | Anchored to trigger | Typical content | Dismiss with |
|---|---|---|---|---|
| Tooltip | No | Yes | 1–2 lines of explanatory text | Cursor leave / focus out |
| Popover | No | Yes | Short interactive content: a form field, a picker, a small list | Click outside, Escape, explicit close |
| Dropdown / Menu | No | Yes | List of actions or options | Click outside, Escape, selection |
| Bottom sheet (mobile) | Partial (dimmed) | No | Actions or content on small screens | Swipe down, tap scrim, Escape |
| Drawer / Side panel | Partial (dimmed) | No | Secondary editing, detail views, long forms | Escape, explicit close; optionally click scrim |
| Dialog / Modal | Yes (full scrim) | No | Blocking task: confirm action, fill required form | Escape (non-destructive only), explicit button |
| Full-screen overlay | Yes (complete) | No | Immersive task: media viewer, complex configuration | Explicit close only |
Decision rule: If the user can continue using the rest of the app while the overlay is open, use a non-blocking type (drawer, popover). If the app must wait for the user's response, use a modal.
A tooltip appears on hover or keyboard focus and disappears when the trigger loses focus. It is purely informational — no interactive elements inside.
role="tooltip" on the element; aria-describedby on the trigger pointing to the tooltip id.A popover is anchored to a trigger but contains interactive content — a colour picker, a date range selector, a small form, a list of filters. Unlike a tooltip, it stays open while the user interacts.
role="dialog" (if interactive) or role="listbox" (if a list); aria-haspopup on the trigger.A dropdown lists selectable options or actions anchored to a trigger button. It is the lightest interactive overlay.
↑/↓ to move between items, Enter to select, Escape to close.On small screens, a bottom sheet replaces modals and popovers. It slides up from the bottom edge and feels native to touch devices.
role="dialog" with the same focus management as a modal.A drawer slides in from the left or right and partially covers the main content. Use it for secondary editing tasks, detail views, or settings that the user might refer back to while using the main content.
rgba(0,0,0,0.4)) behind the drawer dims the main content.role="dialog", aria-modal="true", aria-labelledby pointing to the drawer title.A modal blocks the entire UI with a full scrim. Use it only when the app genuinely cannot continue without the user's response.
┌──────────────────────────────────┐
│ Title [✕] │ ← Header: title + close button
├──────────────────────────────────┤
│ │
│ Body content │ ← Content: scrolls if needed
│ (description, form, media) │
│ │
├──────────────────────────────────┤
│ [Cancel] [Confirm]│ ← Footer: actions, right-aligned
└──────────────────────────────────┘
| Size | Width | Use for |
|---|---|---|
| Small | 360px | Short confirmations, single-field prompts |
| Medium | 480px | Standard dialogs, short forms |
| Large | 640px | Multi-field forms, richer content |
| Full-screen | 100% viewport | Immersive tasks; use sparingly |
Content that overflows the modal height should scroll within the body area only — the header and footer must remain visible.
| Trigger | Allowed for non-destructive? | Allowed for destructive? |
|---|---|---|
Escape key | Yes | No — require explicit Cancel |
| Click outside scrim | Yes (optional) | No — too easy to dismiss accidentally |
| Close button (✕) | Yes | Yes |
| Cancel button | Yes | Yes |
For destructive or irreversible actions: disable Escape and click-outside dismissal. The user must explicitly press Cancel or Confirm.
Avoid opening a modal from inside a modal. It signals an information architecture problem — the task is likely too complex for a single dialog.
If a secondary overlay is unavoidable, use a popover anchored inside the modal rather than another full modal. Never stack two blocking scrim overlays.
Every overlay must manage focus correctly. Broken focus management is one of the most common accessibility failures.
Tab and Shift+Tab cycle within the overlay only; focus cannot escape to the content behind the scrim.Return focus to the element that triggered the overlay. If the trigger no longer exists (the element was deleted), move focus to a logical nearby element.
Use a focus trap library or the native <dialog> element, which handles trapping natively in modern browsers. Rolling a manual focus trap is error-prone.
<div
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
aria-describedby="modal-description"
>
<h2 id="modal-title">Delete project?</h2>
<p id="modal-description">
This will permanently delete "Apollo" and all its data. This cannot be undone.
</p>
<button>Cancel</button>
<button>Delete</button>
</div>
role="dialog" on the containeraria-modal="true" tells screen readers to ignore content behind the overlayaria-labelledby points to the dialog title's idaria-describedby points to the description's id (optional but helpful for confirmations)aria-hidden="true" — screen readers must not read itConfirmation dialogs for destructive actions must name the item and consequence. Generic "Are you sure?" dialogs don't give enough context.
Do:
Delete "Apollo Project"? This will permanently remove all tasks, files, and history. This cannot be undone. [Cancel] [Delete project]
Don't:
Are you sure you want to do this? [No] [Yes]
--color-error / --color-danger, not --color-primary.role="dialog", aria-modal="true", aria-labelledby set correctly?Frequently asked questions
Overlays appear above the main content layer. They range from lightweight popovers (non-blocking, anchored to a trigger) to full blocking modals (require a user response before the app continues). Choosing the right overlay type for the task prevents unnecessary interruption and…
The source record exposes this install command: npx skills add https://github.com/dembrandt/dembrandt-skills --skill "skills/modal-and-overlay-patterns". Inspect the command and pinned source before running it.
Alternatives
coreyhaines31/marketingskills
When the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "should I test this," "which version is better," "test two versions," "statistical significance," "how long should I run this test," "growth experiments," "experiment velocity," "experiment backlog," "ICE score," "experimentation program
coreyhaines31/marketingskills
When the user wants to reduce churn, build cancellation flows, set up save offers, recover failed payments, or implement retention strategies. Also use when the user mentions 'churn,' 'cancel flow,' 'offboarding,' 'save offer,' 'dunning,' 'failed payment recovery,' 'win-back,' 'retention,' 'exit survey,' 'pause subscription,' 'involuntary churn,' 'people keep canceling,' 'churn rate is too high,' 'how do I keep users,' or 'customers are leaving.' Use this whenever someone is losing subscribers o
prowler-cloud/prowler
PostgreSQL indexing best practices for Prowler: index design, partial indexes, partitioned table indexing, EXPLAIN ANALYZE validation, concurrent operations, monitoring, and maintenance. Trigger: When creating or modifying PostgreSQL indexes, analyzing query performance with EXPLAIN, debugging slow queries, reviewing index usage statistics, reindexing, dropping indexes, or working with partitioned table indexes. Also trigger when discussing index strategies, partial indexes, or index maintenance
oaustegard/claude-skills
Generate hierarchical _FEATURES.md files that describe what a codebase DOES from a user/consumer perspective, anchored to source symbols via tree-sitting. Supports large complex codebases through feature-driven decomposition into sub-feature files. Uses a multi-pass synthesis: orientation → detail → overview rewrite. Use when someone says "what does this do", "document features", "feature inventory", "_FEATURES.md", or needs to understand a codebase's purpose before modifying it. Complements tre