revision:
Click this trigger. . to open a modal.
Close a modal by clicking: 1/ off to the side, 2/ clicking the X, or 3/ pressing Escape.
You have opened the first modal!
Now, open the second modal by clicking the link.
Second modal !Nice.This is the second modal.
<div class="spec"> <p><a href="#" class="modal-trigger" data-modal-id="modal1">Click this trigger </a>. . to open a modal.</p> <p>Close a modal by clicking: 1/ off to the side, 2/ clicking the X, or 3/ pressing Escape.</p> <div class="modal-wrapper"> <section class="modal-window" id="modal1"> <header class="modal-header"> <h3>The first modal</h3> <button type="button" class="close-modal-button" aria-label="Close modal window"> X</button> </header> <p>You have opened the first modal!</p> <p>Now, open the second modal by clicking the link.</p> <a href="#" class="modal-trigger" data-modal-id="modal2">Second modal</a> ! </p> </section> <section class="modal-window" id="modal2"> <header class="modal-header"> <h3>The second modal 🤯</h3> <button type="button" class="close-modal-button" aria-label="Close modal window">X</button> </header> <p>Nice.This is the second modal.</p> </section> </div> </div> <style> .modal-wrapper {align-items: center; bottom: 0; display: flex; flex-wrap: wrap; height: 100vh; justify-content: center; left: 0; opacity: 0; position: fixed; right: 0; transition: all 0.2s ease-in-out; visibility: hidden; width: 40%; z-index: 1000;} .modal-wrapper.visible {opacity: 1;visibility: visible;} .modal-window {background-image:linear-gradient(red, yellow, black); border-radius: 1vw; box-shadow: 0 .3vw .7vw rgba(0, 0, 0, 0.3); padding: 2vw; transform: scale(0); transition: 0.2s ease-in-out all; position: absolute; margin: 1vw;} .modal-window.visible {transform: scale(1); position: relative;} .modal-header {align-items: center;border-bottom: .2vw solid blue; display: flex; justify-content: space-between; margin-bottom: 2vw; padding-bottom: 2vw;} .close-modal-button { border: none; background-color: transparent; color: darkgreen; cursor: pointer; font-size: 2vw; padding: 0.2vw;} .close-modal-button:hover {color: black;} .modal-trigger {color:blue; cursor: pointer; text-decoration: underline;} </style> <script> let currentlyOpenModals = {}; const noModalsOpen = () => !Object.keys(currentlyOpenModals).length; const modalWrapper = document.querySelector(".modal-wrapper"); const openModal = modalId => { // If we're opening the first modal, make sure the wrapper becomes visible too if (noModalsOpen()) { modalWrapper.classList.add("visible"); } const modal = document.getElementById(modalId); modal.classList.add("visible"); currentlyOpenModals[modalId] = modal; }; const closeModal = modalId => { if (noModalsOpen()) { return; } const modal = currentlyOpenModals[modalId]; modal.classList.remove("visible"); delete currentlyOpenModals[modalId]; // If we closed the last open modal, hide the wrapper if (noModalsOpen()) { modalWrapper.classList.remove("visible"); } }; const closeAllModals = () => { // Iterate over the IDs in our map and close each modal with that ID Object.keys(currentlyOpenModals).forEach(closeModal); }; const modalTriggers = document.querySelectorAll(".modal-trigger"); modalTriggers.forEach(modalTrigger => { modalTrigger.addEventListener("click", clickEvent => { const trigger = clickEvent.target; const modalId = trigger.getAttribute("data-modal-id"); openModal(modalId); }); }); document.querySelectorAll(".modal-window").forEach(modal => { modal.addEventListener("click", clickEvent => { clickEvent.stopPropagation(); }); }); modalWrapper.addEventListener("click", () => { closeAllModals(); }); document.querySelectorAll(".close-modal-button").forEach(closeModalButton => { closeModalButton.addEventListener("click", clickEvent => { const modalToClose = clickEvent.target.closest(".modal-window"); closeModal(modalToClose.id); }); }); document.body.addEventListener("keyup", keyEvent => { if (keyEvent.key === "Escape") { closeAllModals(); } }); </script>