
A simple, elegant modal popup built with JavaScript and animated with CSS3 transitions & transforms.
How to use it:
Create the modal content following the html structure as these:
<div data-modal="trigger-demo" class="modal">
<article class="content-wrapper">
<button class="close"></button>
<header class="modal-header">
<h2>This is a modal</h2>
</header>
<div class="content">
<p>More modal content here</p>
</div>
<footer class="modal-footer">
<button>Okey</button>
<button>Cancel</button>
</footer>
</article>
</div>Create the trigger button to launch the modal. Note that the ‘data-modal-trigger’ attribute must match the value of the modal’s ‘data-modal’ attribute.
<button data-modal-trigger="trigger-demo" class="trigger"> Launch </button>
The primary CSS/CSS3 rules for the modal popup.
.modal {
display: none;
background-color: transparent;
transition: all 0.25s ease;
}
.modal.open {
position: fixed;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100vh;
background-color: rgba(0, 0, 0, 0.5);
}
.modal .content-wrapper {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
width: 50%;
margin: 0;
padding: 2.5rem;
background-color: white;
border-radius: 0.3125rem;
box-shadow: 0 0 2.5rem rgba(0, 0, 0, 0.5);
}
.modal .content-wrapper .close {
position: absolute;
top: 0.5rem;
right: 0.5rem;
display: flex;
align-items: center;
justify-content: center;
width: 2.5rem;
height: 2.5rem;
border: none;
background-color: transparent;
font-size: 1.5rem;
transition: 0.25s linear;
}
.modal .content-wrapper .close:before, .modal .content-wrapper .close:after {
position: absolute;
content: '';
width: 1.25rem;
height: 0.125rem;
background-color: black;
}
.modal .content-wrapper .close:before { transform: rotate(-45deg); }
.modal .content-wrapper .close:after { transform: rotate(45deg); }
.modal .content-wrapper .close:hover { transform: rotate(360deg); }
.modal .content-wrapper .close:hover:before, .modal .content-wrapper .close:hover:after { background-color: tomato; }
.modal .content-wrapper .modal-header {
position: relative;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
margin: 0;
padding: 0 0 1.25rem;
}
.modal .content-wrapper .modal-header h2 {
font-size: 1.5rem;
font-weight: bold;
}
.modal .content-wrapper .content {
position: relative;
display: flex;
}
.modal .content-wrapper .content p {
font-size: 0.875rem;
line-height: 1.75;
}
.modal .content-wrapper .modal-footer {
position: relative;
display: flex;
align-items: center;
justify-content: flex-end;
width: 100%;
margin: 0;
padding: 1.875rem 0 0;
}
.modal .content-wrapper .modal-footer > button {
margin-left: 0.625rem;
padding: 0.625rem 1.25rem;
border: none;
background-color: slategray;
color: white;
font-size: 0.87rem;
font-weight: 300;
}
.modal .content-wrapper .modal-footer > button:first-child { background-color: #2ecc71; }
.modal .content-wrapper .modal-footer > button:last-child { background-color: #e74c3c; }
The main JavaScript to activate the modal window.
const buttons = document.querySelectorAll(`button[data-modal-trigger]`);
for(let button of buttons) {
modalEvent(button);
}
function modalEvent(button) {
button.addEventListener('click', () => {
const trigger = button.getAttribute('data-modal-trigger');
const modal = document.querySelector(`[data-modal=${trigger}]`);
const contentWrapper = modal.querySelector('.content-wrapper');
const close = modal.querySelector('.close');
close.addEventListener('click', () => modal.classList.remove('open'));
modal.addEventListener('click', () => modal.classList.remove('open'));
contentWrapper.addEventListener('click', (e) => e.stopPropagation());
modal.classList.toggle('open');
});
}






