How they made controls at Github? Modal dialog

  • Episode1: Dropdown
  • Episode2: Modal dialog
  • Episode3: Hamburger menu
  • Episode4: Popup
  • Recap
    In previous episode we saw how to create a dropdown using details and summary tags.
    Present
    In this episode let's see how to create a modal dialog out of details and summary tags.
    When we say modal dialog, it should contain 2 main things.
  • an overlay
  • a container to display content
  • let's start with html
    <details role='dialog'>
        <summary>click me to open a dialog</summary>
        <div>I'm in a dialog. click outside to close me.</div>
    </details>
    when rendered, this displays in an accordion fashion. so let's style it to look like a dialog.
    :root {
      --border-color: #ccc;
      --spacing: 1rem;
      --primary: #fff;
    }
    
    details[role='dialog'] {
      display: inline-block;
    
      summary {
        cursor: pointer;
        border: 1px solid var(--border-color);
        padding: 10px;
      }
    
      summary + div {
        position: fixed;
        top: 0;
        left: 50%;
        transform: translateX(-50%);
        margin: calc(var(--spacing) * 2) auto;
        width: 500px;
        background-color: var(--primary);
        z-index: 2;
        padding: var(--spacing);
      }
    }
    all is good. The dialog says click outside to close me. heck but where is the overlay?? 😕
    you know the secret sauce for this in last episode❗❗
    tadaaaaa
    &[open] summary {
        &::before {
          position: fixed;
          top: 0;
          right: 0;
          bottom: 0;
          left: 0;
          z-index: 1;
          display: block;
          cursor: default;
          content: ' ';
          background-color: rgba(0, 0, 0, 0.5);
        }
      }
    yeahh got it?? but small change. In last episode, the background-color of summary tag is transparent but here in order to give user a sense of overlay we slapped color to background.
    Now let's see the entire css:
    :root {
      --border-color: #ccc;
      --spacing: 1rem;
      --primary: #fff;
    }
    
    details[role='dialog'] {
      display: inline-block;
    
      summary {
        cursor: pointer;
        border: 1px solid var(--border-color);
        padding: 10px;
      }
    
      &[open] summary {
        &::before {
          position: fixed;
          top: 0;
          right: 0;
          bottom: 0;
          left: 0;
          z-index: 1;
          display: block;
          cursor: default;
          content: ' ';
          background-color: rgba(0, 0, 0, 0.5);
        }
      }
    
      summary + div {
        position: fixed;
        top: 0;
        left: 50%;
        transform: translateX(-50%);
        margin: calc(var(--spacing) * 2) auto;
        width: 500px;
        background-color: var(--primary);
        z-index: 2;
        padding: var(--spacing);
      }
    }
    That's it. see how simple it is to create a modal dialog?? But this implementation got its own caveats:
  • you can't stop closing the dialog when user clicks outside. So if you intend to use it, then use it for info dialogs where you just display some static content.
  • Protip
    when you say modal dialog, you need some handlers to do some actions after dialog opens and after it is closed. Don't worry i got you covered. Details tag has ontoggle event which helps us in such scenerios.
    detailsTag.addEventListener('toggle', () => {
      if(detailsTag.open) {
        // do operation when dialog opens
      } else {
        // do operation when dialog closed
      }
    })
    Asusual you can find the working example here.
    See you in next episode. Thanks..
    Kiran 👋

    35

    This website collects cookies to deliver better user experience

    How they made controls at Github? Modal dialog