<div class="cake" id="cake">
<div class="smoke"></div>
<div class="candle"></div>
<div class="top-layer"></div>
<div class="bottom-layer"></div>
</div>
/* CAKE! */
.cake {
position: relative;
width: 100%;
max-width: 320px;
cursor: pointer;
}
/* wick */
.cake::before {
position: absolute;
top: 60px;
left: 49%;
width: 4px;
height: 20px;
background: #555;
content: "";
transform: skew(4deg);
z-index: 5;
}
/* Candle */
.candle {
position: relative;
width: 30px;
height: 80px;
margin-top: 80px;
margin-inline: auto;
border-radius: 5px;
background: linear-gradient(#9fa0ff 50%, transparent 50%), #dab6fc;
background-size: 10px 10px;
z-index: 6;
}
.candle::before,
.candle::after {
display: block;
position: relative;
top: -58px;
left: 18px;
width: 40px;
height: 40px;
border-radius: 80% 0 55% 50% / 55% 0 80% 50%;
background: darkorange;
transform: rotate(-45deg) translateX(-25%);
transform-origin: bottom center;
animation: candleMove 3s infinite;
opacity: 0.9;
content: "";
}
.candle::after {
position: absolute;
top: -53px;
left: 17px;
width: 30px;
height: 30px;
background: orange;
animation: none;
}
/* cake layers */
.top-layer {
position: relative;
width: 78%;
height: 135px;
margin: 0 auto -13%;
border-radius: 56% 46% 46% 56% / 5% 5% 26% 26%;
background: #fff;
background: linear-gradient(90deg, #d7907b 50%, transparent 50%),
radial-gradient(#6c4b5e 90%, transparent 10%), #b3679b;
background-size: 50% 20%, 50% 80%;
background-position: 87.5% 0, -37% -50%;
z-index: 3;
}
.top-layer::before {
position: absolute;
top: 0;
width: 100%;
height: 80px;
border-radius: 50%;
background: #b3679b;
content: "";
transform: translateY(-45%);
z-index: 4;
}
.bottom-layer {
position: relative;
height: 165px;
border-radius: 56% 46% 46% 56% / 5% 5% 20% 20%;
background: radial-gradient(#b3679b 20%, transparent 19%),
radial-gradient(#d7907b 20%, #6c4b5e 19%), #6c4b5e;
background-size: 40px 40px;
background-position: 0 0, 20px 20px;
}
.bottom-layer::before {
position: absolute;
top: 0;
width: 100%;
height: 110px;
border-radius: 50%;
background: #562b0c;
content: "";
transform: translateY(-45%);
z-index: 2;
}
/* Blow smoke-ish */
.blow .candle::before,
.blow .candle::after {
animation: blowout 0.3s forwards;
}
.blow .smoke {
position: absolute;
top: 65px;
left: 50%;
width: 50px;
height: 50px;
margin-left: -25px;
border-radius: 50%;
background: whitesmoke;
opacity: 0;
animation: smoke 4s 0s infinite;
z-index: 3;
}
.blow .smoke::before,
.blow .smoke::after {
position: absolute;
top: 65px;
left: 50%;
width: 50px;
height: 50px;
margin-left: -25px;
border-radius: 50%;
background: whitesmoke;
opacity: 0;
animation: smoke 5s 1s infinite;
content: "";
z-index: 3;
}
.smoke::before {
animation-delay: 0.2s;
}
.smoke::after {
animation-delay: 2s;
}
/* keyframes */
@keyframes candleMove {
0%,
100% {
transform: rotate(-45deg) translateX(-25%) translateY(-1px);
border-radius: 80% 0 55% 50% / 55% 0 80% 50%;
}
30% {
transform: rotate(-43deg) translateX(-25%) translateY(0);
border-radius: 70% 0 55% 50% / 65% 0 80% 50%;
}
50% {
transform: rotate(-47deg) translateX(-25%) translateY(-2px);
border-radius: 80% 0 55% 50% / 55% 0 80% 50%;
}
70% {
transform: rotate(-43deg) translateX(-25%) translateY(0);
border-radius: 70% 0 55% 50% / 65% 0 80% 50%;
}
}
@keyframes blowout {
from {
transform: scaleY(1) rotate(-45deg) translateX(-25%) translateY(-1px);
opacity: 1;
margin-top: 0;
}
to {
transform: scaleY(0) rotate(-45deg) translateX(-20%) translateY(-1px);
opacity: 0;
margin-top: 15px;
}
}
@keyframes smoke {
0% {
transform: scale(0.2) translate(0, 0);
}
10% {
opacity: 1;
transform: scale(0.2) translate(0, 0);
}
100% {
opacity: 0;
transform: scale(1) translate(-20px, -130px);
}
}
/* General styling */
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
background: radial-gradient(#9198e5, #7745ff);
}
const cake = document.getElementById("cake");
cake.addEventListener('click', () => {
cake.classList.toggle('blow');
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.