<!DOCTYPE html>
<!--
This page, its assets and sources are Copyright (C) 2021 Wojtek Kosior,
released under Creative Commons Zero. See:
https://creativecommons.org/publicdomain/zero/1.0/legalcode
Sources available here:
https://git.koszko.org/birthday-flower-css-animation
-->
<html>
<head>
<title>🏶</title>
<style>
div, body {
margin: 0;
padding: 0;
}
img {
user-select: none;
}
html {
width: 100vw;
height: 100vh;
overflow: hidden;
bachground-color: #fff;
}
#picture {
--unit: calc(100vh / 90);
overflow: hidden;
height: calc(90 * var(--unit));
}
#picture h1 {
font-size: var(--unit);
}
#picture>*, .smile, .eyes, .center {
margin-left: auto;
margin-right: auto;
}
.flower {
position: relative;
top: calc(-67 * var(--unit));
width: calc(30 * var(--unit));
height: calc(30 * var(--unit));
}
.flower>* {
position: relative;
width: 0;
height: 0;
}
.center {
top: calc(15 * var(--unit));
transform-origin: 50% 50%;
animation-name: center-appear;
animation-duration: 0;
animation-fill-mode: both;
}
.animated .center {
animation-duration: 0.4s;
}
.center::before {
content: "";
display: block;
width: calc(3 * var(--unit));
height: calc(3 * var(--unit));
background-color: #c80;
border-radius: calc(1.5 * var(--unit));
position: relative;
top: calc(-1.5 * var(--unit));
left: calc(-1.5 * var(--unit));
}
@keyframes center-appear {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
.petal {
top: calc(14.7 * var(--unit));
left: calc(15 * var(--unit));
}
.petal * {
width: calc(var(--subunit) * var(--unit));
animation-duration: 8s;
animation-timing-function: ease-out;
animation-fill-mode: both;
}
.petal>*{
position: relative;
top: calc(-3 * var(--subunit) * var(--unit));
left: calc(-0.5 * var(--subunit) * var(--unit));
transform-origin: 50% 100%;
animation-name: petal-rotate;
}
.petal>*>*{
position: relative;
animation-delay: inherit;
animation-name: petal-come-close;
}
@keyframes petal-rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(var(--end-deg));
}
}
@keyframes petal-come-close {
0% {
bottom: calc(15 * var(--unit));
opacity: 0;
}
100% {
bottom: 0;
opacity: 1;
}
}
.smile {
top: calc(20 * var(--unit));
}
.eyes {
top: calc(5 * var(--unit));
}
.smile>*, .eyes>* {
position: relative;
width: calc(17 * var(--unit));
left: calc(-8.5 * var(--unit));
top: calc(-3 * var(--unit));
animation-fill-mode: both;
}
.smile>* {
animation-name: appear;
animation-duration: 0.3s;
}
@keyframes appear {
0% {
transform: scaleY(0);
}
100% {
transform: scaleY(1);
}
}
.eyes>* {
transform-origin: 50% calc(10.5 * var(--unit));
animation-name: eyes-blink;
animation-duration: 4s;
animation-iteration-count: infinite;
}
@keyframes eyes-blink {
0%, 100% {
transform: scaleY(0);
}
7.5%, 92.5% {
transform: scaleY(1);
}
}
.stem {
position: relative;
top: calc(15 * var(--unit));
background-color: #495;
border-left: solid calc(0.5 * var(--unit)) #252;
border-right: solid calc(0.5 * var(--unit)) #252;
width: var(--unit);
height: calc(75 * var(--unit));
transform-origin: 50% calc(0 * var(--unit));
animation-name: appear;
animation-duration: 0.6s;
animation-fill-mode: both;
}
.najlepszego, .zokazji {
position: relative;
width: 0;
height: 0;
top: calc(-55 * var(--unit));
animation-name: appear;
animation-duration: 0.4s;
animation-fill-mode: both;
}
.zokazji {
top: calc(-35 * var(--unit));
}
.najlepszego>*, .zokazji>* {
position: relative;
width: calc(42 * var(--unit));
left: calc(-21 * var(--unit));
transform-origin: 50% 100%;
animation-name: bounce;
animation-direction: alternate;
animation-iteration-count: infinite;
animation-duration: 1.5s;
animation-fill-mode: both;
animation-timing-function: cubic-bezier(0.01, 0.29, 0, 0.96);
}
@keyframes bounce {
0% {
transform: scaleY(0.7);
}
100% {
transform: scaleY(1.2);
}
}
</style>
</head>
<body>
<div id="picture">
<IMPORT stem.html/>
<div class="flower animated">
<IMPORT center.html/>
<IMPORT petals.html/>
<IMPORT face.html/>
</div>
<IMPORT text.html/>
</div>
</body>
</html>