Should the HTML5 dialog tag be used for a toggleable responsive navigation menu?

Overview

It is common practice to have the primary website navigation always visible on larger devices (desktop and tablet) and shown/hidden with a toggle button (“hamburger menu”) on smaller devices (mobile). Is it best practice to use the HTML5 dialog element for this type of responsive navigation?

Dialog Pros

  1. dialog elements include a native keyboard trap. When a dialog is open, the tab index is isolated to the contents of the dialog, greatly improving the keyboard navigation experience.

  2. dialog elements include native functionality to close model with the escape button.

  3. dialog elements include native functionality to restore focus to the previously focused element when the modal is closed.

  4. dialog elements include native functionality for a backdrop behind the modal.

  5. dialog elements convey the intention of element to the browser allowing the browser to potentially render an element in the best possible way for the device. For example, select elements are rendered different on desktop browser than mobile browsers.

Dialog Cons

  1. There could be SEO implications to placing the primary navigation in a dialog element. In an effort to circumvent possible consequences, the dialog element includes the open attribute.

  2. The dialog element is technically never opened on larger devices. Instead, the dialog element is set to display: block. If the dialog is opened (dialog.show()) when the browser width increases, it causes the focus to change. The `display:block; hack, circumvents the issue. This a typical implementation could cause issues on some devices.

Example

    const dialog = document.querySelector('header dialog');
    const header = document.querySelector('header');

    function resize() {
      if (!window.matchMedia('(max-width: 640px)').matches) {
        dialog.close();
      }
    }

    dialog.removeAttribute('open');
    window.addEventListener('resize', resize);
    resize();

    document.querySelector('.open').addEventListener('click', () => {
        dialog.showModal();
    });

    document.querySelector('.close').addEventListener('click', () => {
        dialog.close();
    });
body {
      margin: 0;
    }

    main {
      padding: 1rem;
    }

    dialog::backdrop {
      background-color: rgba(0, 0, 0, 0.75);
    }

    header dialog {
      width: auto;
      height: auto;     
      border: none;
      padding: 1rem;
      background-color: #333;
      color: #FFF;
    }

    header dialog a {
      color: #FFF;
    }
      
    header ul {
      list-style: none;
      margin: 0;
      padding: 0;
      display: flex;
      gap: 1rem;
    }
    
    @media (min-width: 641px) {
      header dialog {
        position: static;
        display: block; /* Force closed dialog to be visible on larger devices */
        margin: 0; /* Necessary to fix niche rending bug when going from narrow to wide with an open dialog */
      }
      
      header .close,
      header .open {
        display: none !important;
      }
    }
    
    @media (max-width: 640px) {
      header dialog {
        max-width: none;
        max-height: none;
        margin: 0;
        width: auto;
        padding: 1rem;
        text-align: center;
      }

      header ul {
        flex-direction: column;
        margin-bottom: 1rem;
      }
    }
<header>
  <dialog open> <!-- dialog is set to open in case search engines ignore closed dialogs -->
    <nav>
      <ul>
        <li><a href="#">Home</a></li>
        <li><a href="#">About</a></li>
        <li><a href="#">Contact</a></li>
      </ul>
    </nav>
    <button class="close">Close</button>  
  </dialog>
  <button class="open">Menu</button>
</header>