skip to Main Content

When opening my dialog using the "Open" button, you can see that the content is not shrinking.

However, when opening it with the "Open Modal" button, the content is shrinking. How can I prevent this? I do not want a solution where I need to add white-space: nowrap; or other properties to every single thing inside the dialog, I am looking for a generic solution which will make the modal dialog behave like the modeless one.

PS: I am doing things the way I do them because I am working on a fallback for the dialog element. So I cannot just use the dialog element and I ideally do not want to add extra markup.

const dialog = document.getElementById("dialog");

document.getElementById("open").addEventListener("click", () => {
    dialog.classList.add("open");
});

document.getElementById("openModal").addEventListener("click", () => {
    dialog.classList.add("open", "modal");
});

document.getElementById("close").addEventListener("click", () => {
    dialog.classList.remove("open", "modal");
});
.dialog {
    display: none;
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: salmon;
    padding: 1rem;
}
.dialog.modal {
    border-width: max(100vh, 100vw);
    border-style: solid;
    border-color: rgba(0, 0, 0, 0.3);
    background-clip: padding-box;
    backdrop-filter: blur(2px);
}
.dialog.open {
    display: block;
}
<div class="dialog" id="dialog">
  <p>This is my dialog box</p>
  <button id="close">Close</button>
</div>

<button id="open">Open</button>

<button id="openModal">Open Modal</button>

2

Answers


  1. Well, using border in this way isn’t "normal" to begin with. It’s much more common and less problematic to simply use a pseudo-element to create the mask.

    Because text is free to wrap, and because you’ve given your border fluid sizing, the border fills the space that’s not otherwise allocated (the largest space that allows the longest word in your text).

    I suggest you take a more conventional approach and use a mask element instead. Note that I’ve applied z-index to the dialog to keep it over the mask.

    const dialog = document.getElementById("dialog");
    
    document.getElementById("open").addEventListener("click", () => {
      dialog.classList.add("open");
    });
    
    document.getElementById("openModal").addEventListener("click", () => {
      dialog.classList.add("open", "modal");
      document.body.classList.add('modal-open');
    });
    
    document.getElementById("close").addEventListener("click", () => {
      dialog.classList.remove("open", "modal");
      document.body.classList.remove('modal-open');
    });
    .dialog {
      display: none;
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      background: salmon;
      padding: 1rem;
      z-index: 1;
    }
    
    body.modal-open::after {
      content: '';
      position: fixed;
      top: 0;
      left: 0;
      width: 100vw;
      height: 100vh;
      background-color: rgba(0, 0, 0, 0.3);
      backdrop-filter: blur(2px);
    }
    
    .dialog.open {
      display: block;
    }
    <div class="dialog" id="dialog">
      <p>This is my dialog box</p>
      <button id="close">Close</button>
    </div>
    
    <button id="open">Open</button>
    
    <button id="openModal">Open Modal</button>
    Login or Signup to reply.
  2. If you are creating a dialog, use the dialog HTML element. This also provides you with an out of the box way to style the background.

    For this simple example, I added a check if the dialog is already shown before opening the modal, otherwise it would throw an error.

    const dialog = document.querySelector("dialog");
    
    document.getElementById("open").addEventListener("click", () => {
      dialog.show();
    });
    
    document.getElementById("openModal").addEventListener("click", () => {
      if (dialog.open) { 
        dialog.close()
      }
      dialog.showModal();
    });
    
    document.getElementById("close").addEventListener("click", () => {
      dialog.close();
    });
    dialog {
      background: salmon;
      /*background color for the dialog + modal*/
    }
    
    
    /*
    some fancy gradient for the backdrop!
    */
    
    ::backdrop {
      background-image: linear-gradient( 45deg, magenta, rebeccapurple, dodgerblue, green);
      opacity: 0.75;
    }
    <dialog>
      <p>This is my dialog box</p>
      <button type="button" id="close">Close</button>
    </dialog>
    
    <button id="open">Open</button>
    
    <button id="openModal">Open Modal</button>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search