Modals

Dialog windows that overlay the main content with backdrop and animations.

Basic Modal Structure

Modals consist of a backdrop, dialog container, header, body, and optional footer.

<!-- Modal Backdrop -->
<div class="modal-backdrop">
  <!-- Modal Dialog -->
  <div class="modal">
    <div class="modal-header">
      <h3>Modal Title</h3>
      <button class="modal-close">×</button>
    </div>
    <div class="modal-body">
      <p>Modal content goes here...</p>
    </div>
    <div class="modal-footer">
      <button class="btn-ghost">Cancel</button>
      <button class="btn-primary">Confirm</button>
    </div>
  </div>
</div>
Note: Modals require JavaScript to show/hide. Add display: flex to modal-backdrop to show the modal, or display: none to hide it.

Modal Sizes

Control modal width with size modifiers.

<!-- Small Modal -->
<div class="modal modal-sm">...</div>

<!-- Default Modal -->
<div class="modal">...</div>

<!-- Large Modal -->
<div class="modal modal-lg">...</div>

<!-- Extra Large Modal -->
<div class="modal modal-xl">...</div>

<!-- Fullscreen Modal -->
<div class="modal modal-fullscreen">...</div>

Confirmation Dialog

A common pattern for destructive actions.

<div class="modal-backdrop" style="display: none;">
  <div class="modal modal-sm">
    <div class="modal-header">
      <h3>Delete Account</h3>
      <button class="modal-close">×</button>
    </div>
    <div class="modal-body">
      <p>Are you sure you want to delete your account? This action cannot be undone.</p>
    </div>
    <div class="modal-footer">
      <button class="btn-ghost">Cancel</button>
      <button class="btn-danger">Delete Account</button>
    </div>
  </div>
</div>

Form Modal

Use modals to collect user input without navigating away.

<div class="modal-backdrop" style="display: none;">
  <div class="modal">
    <div class="modal-header">
      <h3>Add New User</h3>
      <button class="modal-close">×</button>
    </div>
    <div class="modal-body">
      <form>
        <div class="form-group">
          <label for="username">Username</label>
          <input type="text" id="username" class="form-input" required>
        </div>
        <div class="form-group">
          <label for="email">Email</label>
          <input type="email" id="email" class="form-input" required>
        </div>
        <div class="form-group">
          <label for="role">Role</label>
          <select id="role" class="form-select">
            <option>Admin</option>
            <option>User</option>
            <option>Guest</option>
          </select>
        </div>
      </form>
    </div>
    <div class="modal-footer">
      <button class="btn-ghost">Cancel</button>
      <button class="btn-primary">Add User</button>
    </div>
  </div>
</div>

JavaScript Example

Simple JavaScript to open and close modals.

// Open modal
function openModal(modalId) {
  const modal = document.getElementById(modalId);
  modal.style.display = 'flex';
  document.body.style.overflow = 'hidden';
}

// Close modal
function closeModal(modalId) {
  const modal = document.getElementById(modalId);
  modal.style.display = 'none';
  document.body.style.overflow = '';
}

// Close on backdrop click
document.querySelectorAll('.modal-backdrop').forEach(backdrop => {
  backdrop.addEventListener('click', (e) => {
    if (e.target === backdrop) {
      closeModal(backdrop.id);
    }
  });
});

// Close on ESC key
document.addEventListener('keydown', (e) => {
  if (e.key === 'Escape') {
    document.querySelectorAll('.modal-backdrop').forEach(backdrop => {
      if (backdrop.style.display === 'flex') {
        closeModal(backdrop.id);
      }
    });
  }
});

Best Practices

✓ Do

  • Keep content focused and concise
  • Provide clear action buttons
  • Allow ESC key to close
  • Disable background scrolling
  • Use for important interruptions only

✗ Don't

  • Show multiple modals at once
  • Use for non-essential information
  • Make modals too large or complex
  • Prevent closing the modal
  • Auto-open on page load (usually)

Accessibility

Best Practices:
  • Use role="dialog" and aria-modal="true" on modal
  • Add aria-labelledby pointing to modal title
  • Trap focus within modal when open
  • Return focus to trigger element on close
  • Allow ESC key to close modal
  • Ensure keyboard navigation works properly
  • Use semantic button elements for close actions