<div class="toast-container">
</div>
<button onClick="add()">Add</div>
<svg class="filters"><defs>
<filter id="goo">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" result="blur"/>
<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 30 -15" result="filter"/>
</filter>
</defs>
</svg>
html {
font-family: sans-serif;
}
:root {
--toast-gap: 10px;
--drop-start-color: #000;
--toast-background: #000;
--toast-foreground: #FFF;
}
.toast-container {
position: fixed;
top: 0;
inset-inline: 0;
display:flex;
flex-direction: column;
align-items: center;
gap: calc(0.5 * var(--toast-gap));
padding: var(--toast-gap);
pointer-events: none;
}
.toast {
position: relative;
}
.toast-content {
position: relative;
background: var(--toast-background);
color: var(--toast-foreground);
padding: 13px;
min-width: 300px;
border-radius: 32px;
opacity: 0;
z-index: 2;
animation: fade forwards 0.1s;
animation-delay: 0.5s;
pointer-events: auto;
display: flex;
align-items: center;
gap: 10px;
&:before {
content: "";
display: block;
width: 20px;
height: 20px;
border-radius: 20px;
background: #18baff;
}
}
.toast-animator {
--bar-height: 20px;
background: var(--drop-start-color);
position: absolute;
left: 50%;
top: calc(-1 * (var(--toast-gap) + var(--bar-height)));
width: 100%;
height: var(--bar-height);
translate: -50%;
border-radius: 50px;
z-index:1;
filter: url(#goo);
animation: hide forwards 1ms, background forwards 1ms;
animation-delay: 1s, 0.3s;
&:before {
background: var(--toast-background);
content: "";
position: absolute;
visibility: visible;
animation:
ball 0.4s forwards cubic-bezier(.55,-0.01,.34,1.28),
morph 0.6s forwards cubic-bezier(.55,-0.01,.34,1.28),
hide 1ms forwards;
animation-delay: 0s, 0s, 0.6s;
left: 50%;
top: -150%;
translate: -50%;
width: 50px;
height: 45px;
border-radius: 50px;
}
}
.toast:nth-child(n+2) .toast-animator {
display: none;
}
@keyframes ball {
0% {
top: -150%;
}
100% {
top: 150%;
}
}
@keyframes morph {
20% {
width: 50px;
}
100% {
width: 100%;
border-radius: 32px;
}
}
@keyframes fade {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes hide {
0% {
visibility: visible;
}
100% {
visibility: hidden;
}
}
@keyframes background {
0% {
background: var(--toast-background);
}
100% {
background: transparent;
}
}
let id = 0;
function add() {
var toast = document.createElement("div");
toast.classList.add("toast");
toast.innerHTML = `<div class="toast-animator"></div>
<div class="toast-content">TOAST</div>`;
toast.style.viewTransitionName = `toast-${id}`;
id++;
document.startViewTransition(() => {
document.querySelector(".toast-container").prepend(toast);
});
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.