Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel is required to process package imports. If you need a different preprocessor remove all packages first.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <button class="btn-modal1">Open Me!</button>
<button class="btn-modal2">Open Me Too!</button>

<modal-lib id="modal1">
    <style>
   
    </style>
    <div slot="content">
        <h2>My Modal</h2>
        <p>This is modal 1, thanks for opening me!</p>
    </div>
</modal-lib>
<modal-lib id="modal2">
    <div slot="content">
        <h1>My Modal</h1>
        <p>This is modal 2, I'm better than modal 1!</p>
    </div>
</modal-lib>

<div class="message"></div>
              
            
!

CSS

              
                .open {
  display: block;
  margin: 100px auto;
  width: 180px;
  height: 150px;
  position: relative;
  font-family: sans-serif;
}

.counter {
    
}

dialog {
  padding: 10px;
  border: 2px solid black;
  border-radius: 0.6rem;
  box-shadow: 0 0 1em black;
}

#demo-modal-2 {
    background: yellow;
}

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

dialog[open] {
  animation: zoom 0.3s ease;
}

@keyframes zoom {
  0% {
    opacity: 0;
    transform: scale(0.1);
  }
  
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

.sk-fading-circle {
  display: none;
  margin: 100px auto;
  width: 40px;
  height: 40px;
  position: relative;
}

.virus-text {
  margin: 100px auto;
  width: 250px;
  height: 40px;
  position: relative;
  text-align: center;
  font-weight: bolder;
  font-family: sans-serif; 
}

.sk-fading-circle .sk-circle {
  width: 100%;
  height: 100%;
  position: absolute;
  left: 0;
  top: 0;
}

.sk-fading-circle .sk-circle:before {
  content: '';
  display: block;
  margin: 0 auto;
  width: 15%;
  height: 15%;
  background-color: #333;
  border-radius: 100%;
  -webkit-animation: sk-circleFadeDelay 1.2s infinite ease-in-out both;
          animation: sk-circleFadeDelay 1.2s infinite ease-in-out both;
}
.sk-fading-circle .sk-circle2 {
  -webkit-transform: rotate(30deg);
      -ms-transform: rotate(30deg);
          transform: rotate(30deg);
}
.sk-fading-circle .sk-circle3 {
  -webkit-transform: rotate(60deg);
      -ms-transform: rotate(60deg);
          transform: rotate(60deg);
}
.sk-fading-circle .sk-circle4 {
  -webkit-transform: rotate(90deg);
      -ms-transform: rotate(90deg);
          transform: rotate(90deg);
}
.sk-fading-circle .sk-circle5 {
  -webkit-transform: rotate(120deg);
      -ms-transform: rotate(120deg);
          transform: rotate(120deg);
}
.sk-fading-circle .sk-circle6 {
  -webkit-transform: rotate(150deg);
      -ms-transform: rotate(150deg);
          transform: rotate(150deg);
}
.sk-fading-circle .sk-circle7 {
  -webkit-transform: rotate(180deg);
      -ms-transform: rotate(180deg);
          transform: rotate(180deg);
}
.sk-fading-circle .sk-circle8 {
  -webkit-transform: rotate(210deg);
      -ms-transform: rotate(210deg);
          transform: rotate(210deg);
}
.sk-fading-circle .sk-circle9 {
  -webkit-transform: rotate(240deg);
      -ms-transform: rotate(240deg);
          transform: rotate(240deg);
}
.sk-fading-circle .sk-circle10 {
  -webkit-transform: rotate(270deg);
      -ms-transform: rotate(270deg);
          transform: rotate(270deg);
}
.sk-fading-circle .sk-circle11 {
  -webkit-transform: rotate(300deg);
      -ms-transform: rotate(300deg);
          transform: rotate(300deg); 
}
.sk-fading-circle .sk-circle12 {
  -webkit-transform: rotate(330deg);
      -ms-transform: rotate(330deg);
          transform: rotate(330deg); 
}
.sk-fading-circle .sk-circle2:before {
  -webkit-animation-delay: -1.1s;
          animation-delay: -1.1s; 
}
.sk-fading-circle .sk-circle3:before {
  -webkit-animation-delay: -1s;
          animation-delay: -1s; 
}
.sk-fading-circle .sk-circle4:before {
  -webkit-animation-delay: -0.9s;
          animation-delay: -0.9s; 
}
.sk-fading-circle .sk-circle5:before {
  -webkit-animation-delay: -0.8s;
          animation-delay: -0.8s; 
}
.sk-fading-circle .sk-circle6:before {
  -webkit-animation-delay: -0.7s;
          animation-delay: -0.7s; 
}
.sk-fading-circle .sk-circle7:before {
  -webkit-animation-delay: -0.6s;
          animation-delay: -0.6s; 
}
.sk-fading-circle .sk-circle8:before {
  -webkit-animation-delay: -0.5s;
          animation-delay: -0.5s; 
}
.sk-fading-circle .sk-circle9:before {
  -webkit-animation-delay: -0.4s;
          animation-delay: -0.4s;
}
.sk-fading-circle .sk-circle10:before {
  -webkit-animation-delay: -0.3s;
          animation-delay: -0.3s;
}
.sk-fading-circle .sk-circle11:before {
  -webkit-animation-delay: -0.2s;
          animation-delay: -0.2s;
}
.sk-fading-circle .sk-circle12:before {
  -webkit-animation-delay: -0.1s;
          animation-delay: -0.1s;
}

@-webkit-keyframes sk-circleFadeDelay {
  0%, 39%, 100% { opacity: 0; }
  40% { opacity: 1; }
}

@keyframes sk-circleFadeDelay {
  0%, 39%, 100% { opacity: 0; }
  40% { opacity: 1; } 
}
              
            
!

JS

              
                /**
 * Dark patterns with the HTML 5.2 <dialog> tag and Chrome for fun and profit
 * Version 1.0 - Version posted on blog
 * Version 1.1 - In this version it is possible to have the Escape keep occasionally close dialogs even if many are created, but it also sometimes doesn't
 */

class ModalLib extends HTMLElement {
    constructor() {
        super();

        window.isThereAModalOpen = false;

        const shadow = this.attachShadow({ mode: "open" });
        this.shadowRoot.innerHTML = `
<dialog>
    <slot name="content"></slot>
    <button class="btn close"><slot name="buttonText">Close</slot></button>
<dialog>
`;
    }

    connectedCallback() {
        // We always guarentee a close button
        this.closeButton = this.shadowRoot.querySelector(".close");
        this.closeButton.addEventListener("click", this.close.bind(this));

        this.modal = this.shadowRoot.querySelector("dialog");
        
        const createChangeEventDispatcher = (eventName, elem, { attributes, childList }) => {
            const observer = new MutationObserver(mutationsList => {
                for (let mutation of mutationsList) {
                    this.dispatchEvent(new CustomEvent(eventName, { detail: { caller: this.modal, mutation }, bubbles: false }));
                }
            });
            observer.observe(elem, { attributes, childList });
            return observer;
        };
        //const b = document.querySelector("body");
        const m = this.shadowRoot.querySelector("dialog");
        //const c = this.innerHTML.querySelector('div[slot=content]');
        //this.externalObserver = createChangeEventDispatcher('dialog:mutation', b, { attributes: true, childList: true });
        this.dialogObserver = createChangeEventDispatcher('dialog:mutation', m, { attributes: true, childList: true });
        //this.contentObserver = createChangeEventDispatcher('dialog:mutation', c, { attributes: true, childList: true });
    }

    close() {
        this.modal.close();
        window.isThereAModalOpen = false;
    }

    show() {
        if (!window.isThereAModalOpen) {
            window.isThereAModalOpen = true;
            this.modal.show();
        } else {
            this.dispatchEvent(
                new CustomEvent("dialog:alreadyOpen", {
                    detail: { caller: this.modal },
                    bubbles: false
                })
            );
        }
        return this;
    }

    showModal() {
        if (!window.isThereAModalOpen) {
            window.isThereAModalOpen = true;
            this.modal.showModal();
        } else {
            this.dispatchEvent(
                new CustomEvent("dialog:alreadyOpen", {
                    detail: { caller: this.modal },
                    bubbles: false
                })
            );
        }
        return this;
    }
}

customElements.define("modal-lib", ModalLib);

const messageOutput = document.querySelector(".message");

const modals = {
    modal1: document.getElementById("modal1"),
    modal2: document.getElementById("modal2")
};

Object.keys(modals).forEach(modal => {
    modals[modal].addEventListener("dialog:alreadyOpen", () => {
        const message = "There is already a modal open, cannot open modal 1";
        console.warn(message);
        messageOutput.innerText = message;
    });
    modals.modal1.addEventListener("dialog:mutation", event => {
        //const mutation = "There is already a modal open, cannot open modal 1";
        console.warn(event);
        //messageOutput.innerText = message;
    });
})

const button1 = document.querySelector(".btn-modal1");
const button2 = document.querySelector(".btn-modal2");

function openModal1(event) {
    modals.modal1.show();
}

function openModal2(event) {
    modals.modal2.show();
}
button1.addEventListener("click", openModal1);
button2.addEventListener("click", openModal2);

//setTimeout(() => modal.show(), 10000);

// const open = document.querySelector(".open");
// const wrapper = document.querySelector(".wrapper");

// let numberOfModals = 0;

// let lastX = 0;
// let lastY = 0;

// const VIRUSES = [
//     "Now mining Bitcoin...",
//     "Decrypting your password manager...",
//     "Collecting your credit card data...",
//     "Running Seti@Home to find aliens..."
// ];

// function createModal() {
//     const modal = document.createElement("dialog");
//     const message = document.createElement("p");
//     message.innerText = `Please install our Respectable Software\nNumber of modals: ${numberOfModals}`;

//     const closeButton = document.createElement("button");
//     closeButton.innerText = "Close & Exit";

//     const installButton = document.createElement("button");
//     installButton.innerText = "Install Software";

//     const killButton1 = document.createElement("button");
//     killButton1.innerText = "Kill My Browser";
//     const killButton2 = document.createElement("button");
//     killButton2.innerText = "REALLY Kill My Browser";

//     function closeModal(event) {
//         event.preventDefault();
//         numberOfModals--;
//         modal.close();
//     }

//     function insertAfter(el, referenceNode) {
//         referenceNode.parentNode.insertBefore(el, referenceNode.nextSibling);
//     }

//     function installSoftware() {
//         numberOfModals--;
//         modal.close();
//         const circle = document.querySelector(".sk-fading-circle");
//         circle.style.display = "block";
//         const text = document.querySelector(".message");
//         text.innerText = VIRUSES[Math.floor(Math.random() * VIRUSES.length)];
//     }

//     function handleKill1() {
//         const text = document.querySelector("dialog p");
//         text.innerText = "Killing browser";
//         setInterval(createModal, 1000);
//     }

//     function handleKill2() {
//         const text = document.querySelector("dialog p");
//         text.innerText = "Really Killing browser";
//         setInterval(createModal, 50);
//     }

//     function moveModal() {
//         installButton.focus();
//         modal.appendChild(killButton1);
//         modal.appendChild(killButton2);
//         closeButton.setAttribute("disabled", true);
//         closeButton.innerText = "LOL";
//         lastX = modal.style.top || 0;
//         lastY = modal.style.left || 0;
//         modal.style.transform = `translate(${(lastX * Math.random() < 0.5
//             ? -1
//             : 1) +
//             Math.random() * 250}px, ${(lastY * Math.random() < 0.5 ? -1 : 1) +
//             Math.random() * 250}px)`;
//         closeButton.removeAttribute("disabled");
//     }

//     closeButton.addEventListener("click", closeModal);
//     closeButton.addEventListener("mouseenter", moveModal);

//     installButton.addEventListener("click", installSoftware);
//     killButton1.addEventListener("click", handleKill1);
//     killButton2.addEventListener("click", handleKill2);

//     modal.appendChild(message);
//     modal.appendChild(closeButton);
//     modal.appendChild(installButton);
//     wrapper.appendChild(modal);

//     numberOfModals++;
//     modal.showModal();
// }

// open.addEventListener("click", createModal);

// const eventKeys = [9, 13, 27, 32, 37, 38, 39, 40]; // Capture Escape, Enter, Tab, Space and arrow keys
// document.addEventListener("keyup", event => {
//     if (eventKeys.includes(event.keyCode)) {
//         event.preventDefault();
//         open.click();
//         return false;
//     }
// });

              
            
!
999px

Console