<h1>
This demo requires <a href="https://caniuse.com/#feat=web-animation">a supporting browser.</a>
</h1>
<div class="modal">
<div class="text">
<h2>I am a modal!</h2>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit.</p>
</div>
</div>
<button>Click Me</button>
.modal {
background: #daeafa;
border: 1px solid #33b4ff;
padding: 1.5rem;
width: 300px;
border-radius: 20px;
transform: scale(0);
transform-origin: bottom;
}
.text {
opacity: 0;
}
/* Etc */
h1 {
font-size: 1.5rem;
}
h2 {
font-size: 1.5rem;
margin-bottom: 1rem;
}
body {
font-family: system-ui, serif;
display: grid;
height: 100vh;
place-items: center;
}
// Demo by Una Kravets & Kevin Ellis
const $ = (name) => {
return document.querySelector(name);
};
const openModal = [
{ transform: "scaleY(0) scaleX(0)" },
{ transform: "scaleY(1) scaleX(0.01)", offset: 0.3, easing: "ease-in" },
{ transform: "scaleX(0.01)", offset: 0.3, easing: "ease-out" },
{ transform: "scaleX(1)", offset: 1 }
];
const openModalSettings = {
duration: 1000, // 1s
iterations: 1, // single iteration
easing: "ease-out", // easing function
fill: "both" // animation fill mode
};
let open = false;
$("button").addEventListener("click", () => {
// Create two play-pending animations.
let animations = [
$(".modal").animate(openModal, openModalSettings),
$(".text").animate({ opacity: [0, 1] }, openModalSettings)
];
// Pause one of the animations and delay it's start until the
// other is finished.
if (open) {
animations.forEach((anim) => {
anim.currentTime = anim.effect.getTiming().duration;
anim.reverse();
});
animations = animations.reverse();
}
// Run animations sequentially.
animations[1].pause();
animations[0].finished.then(() => {
animations[1].play();
});
open = !open;
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.