Skip to content

Focus When Dialog Closes — Returning Focus After Dialog Dismissal

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about Focus When Dialog Closes. We cover key concepts, practical examples, and best practices to help you master this topic.

When a dialog closes, focus must return to the element that triggered the dialog, maintaining the user's context and preventing disorientation.

In this tutorial, you'll learn Focus Management for dialog dismissal.

What You'll Learn

By the end of this lesson, you'll understand the importance of focus restoration, how to store and restore the trigger element, and how to handle edge cases.

Why It Matters

Without focus restoration, users are left at the top of the page or at an unexpected location after dismissing a dialog, requiring them to navigate back to their previous position.

Real-World Use

Doda Browser's settings dialog stores the trigger element reference on open and restores focus when the dialog closes.

Focus Restoration Flow

flowchart LR
  A[User clicks trigger] --> B[Store trigger reference]
  B --> C[Open dialog]
  C --> D[User dismisses dialog]
  D --> E[Restore focus to trigger]
  E --> F[User continues from original position]

Implementing Focus Restoration

class DialogManager {
  constructor() {
    this.lastTrigger = null;
  }

  open(dialog, trigger) {
    this.lastTrigger = trigger;
    dialog.hidden = false;

    const focusable = dialog.querySelector(
      'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
    );
    (focusable || dialog).focus();
  }

  close(dialog) {
    dialog.hidden = true;

    if (this.lastTrigger && document.contains(this.lastTrigger)) {
      this.lastTrigger.focus();
    }

    this.lastTrigger = null;
  }
}

const dialogManager = new DialogManager();

Handling Multiple Dialogs

class DialogStack {
  constructor() {
    this.stack = [];
  }

  open(dialog, trigger) {
    this.stack.push({ dialog, trigger });
    dialog.hidden = false;
    // Focus first element
  }

  close(dialog) {
    const entry = this.stack.pop();
    dialog.hidden = true;

    if (entry && entry.trigger && document.contains(entry.trigger)) {
      entry.trigger.focus();
    }
  }
}

Deletion Scenarios

When the trigger element no longer exists (e.g., it was removed during dialog interaction), find a reasonable alternative:

function closeDialog(dialog, trigger) {
  dialog.hidden = true;

  if (document.contains(trigger)) {
    trigger.focus();
  } else {
    // Fallback: focus the first element in the previous section
    document.querySelector('main h1').focus();
  }
}

Common Mistakes

  • Not restoring focus: User is left at the top of the page.
  • Restoring focus to the wrong element: The trigger reference was overwritten by another dialog.
  • Not checking if the trigger still exists: The trigger may have been removed or disabled.
  • Restoring focus to a hidden element: The trigger may have been hidden during the dialog.
  • Not handling nested dialogs: Each dialog must restore focus to its own trigger.

Practice and Challenge

1. Where should focus go when a dialog closes? Back to the element that triggered the dialog.

2. Why store the trigger element on open? Because the user may interact with other elements while the dialog is open.

3. What if the trigger element no longer exists? Focus a reasonable alternative, like the main heading.

4. How do you handle nested dialogs? Use a stack to store trigger references for each level.

5. Challenge: Implement a dialog with nested confirmations. Ensure each level restores focus to its correct trigger.

FAQ

Should I always restore focus?

Yes. Focus restoration is a WCAG requirement (SC 2.4.3 Focus Order).

What if the trigger was a keyboard shortcut?

Focus the element that has processing responsibility for the action.

Does focus restoration work in single-page apps?

Yes, as long as the trigger element still exists in the DOM.

Should I restore focus after a form submission dialog?

Yes. If the form succeeded, focus the confirmation message. If cancelled, focus the trigger.

What if the page content has changed significantly?

In SPAs, navigate focus to the nearest logical element if the trigger no longer exists.

Mini Project

Build a dialog system with full focus restoration. Handle: single dialog, nested dialogs, trigger removal, and fallback focus.

What's Next

Continue to Focus Trap Implementation to learn about building a robust focus trap.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro