Skip to content

Instantly share code, notes, and snippets.

@xkeshav
Created December 25, 2022 04:03
Show Gist options
  • Save xkeshav/89f92d3f311484c068532774b4957363 to your computer and use it in GitHub Desktop.
Save xkeshav/89f92d3f311484c068532774b4957363 to your computer and use it in GitHub Desktop.
CSS Christmas Tree πŸŽ„ [Click to restart]
<!-- .tree>.tree__ring[style="--index: $;"]*10>.tree__bauble -->
<div class="tree">
<svg class="tree__star" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 113.32 108.44" style="--delay: 0;">
<path d="M90.19 104.33L57.12 87.38 24.4 105l5.91-36.69L3.44 42.65l36.72-5.72 16.1-33.5L73.06 36.6l36.83 4.97-26.35 26.21z" fill="none" stroke-width="6.88" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
<div class="tree__ring" style="--index: 1;">
<div class="tree__bauble"></div>
<div class="tree__bauble"></div>
</div>
<div class="tree__ring" style="--index: 2;">
<div class="tree__bauble"></div>
<div class="tree__bauble"></div>
</div>
<div class="tree__ring" style="--index: 3;">
<div class="tree__bauble"></div>
<div class="tree__bauble"></div>
</div>
<div class="tree__ring" style="--index: 4;">
<div class="tree__bauble"></div>
<div class="tree__bauble"></div>
</div>
<div class="tree__ring" style="--index: 5;">
<div class="tree__bauble"></div>
<div class="tree__bauble"></div>
</div>
<div class="tree__ring" style="--index: 6;">
<div class="tree__bauble"></div>
<div class="tree__bauble"></div>
</div>
<div class="tree__ring" style="--index: 7;">
<div class="tree__bauble"></div>
<div class="tree__bauble"></div>
</div>
<div class="tree__ring" style="--index: 8;">
<div class="tree__bauble"></div>
<div class="tree__bauble"></div>
</div>
<div class="tree__ring" style="--index: 9;">
<div class="tree__bauble"></div>
<div class="tree__bauble"></div>
</div>
<div class="tree__ring" style="--index: 10;">
<div class="tree__bauble"></div>
<div class="tree__bauble"></div>
</div>
</div>
const RESET = () => {
const MARKUP = document.body.innerHTML
document.body.innerHTML = ''
requestAnimationFrame(() => {
document.body.innerHTML = MARKUP
})
}
document.body.addEventListener('click', RESET)
* {
transform-style: preserve-3d;
}
:root {
--reveal: 1;
--size: 35vmin;
--step: 0.12s;
--star-delay: 2;
--ring-delay: 1;
--reveal-delay: 3s;
--ring: hsl(0 0% 100% / 0.2);
--bauble-one: 6;
--bauble-two: 130;
}
body {
min-height: 100vh;
display: grid;
place-items: center;
background: hsl(210 20% 10%);
}
.tree {
aspect-ratio: 3 / 5;
width: var(--size);
display: grid;
transform: rotateX(24deg) rotateY(-24deg);
}
.tree__ring {
position: relative;
opacity: 1;
animation: jump calc((var(--index) + 1) * 0.2s) calc(var(--ring-delay) * 1s) both;
}
@keyframes jump {
0% {
transform: translateY(calc((10 - var(--index)) * (5/3 * var(--size)) / 10));
}
}
.tree__ring:after {
content: "";
width: calc(var(--size) * (var(--index) / 10));
aspect-ratio: 1;
border-radius: 50%;
border: 4px solid var(--ring);
position: absolute;
box-sizing: border-box;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotateX(90deg);
}
.tree__bauble {
position: absolute;
inset: 0;
transform: rotateY(var(--rotate, 0deg));
animation: spin 2s calc(var(--index) * var(--step)) infinite linear;
}
.tree__bauble:last-of-type {
--rotate: 90deg;
--hue: var(--bauble-two, 140);
}
@keyframes reveal {
0% {
opacity: 0;
}
}
@keyframes spin {
to {
transform: rotateY(calc(var(--rotate, 0deg) + 360deg));
}
}
.tree__star {
stroke-width: calc(var(--size) * 0.25);
stroke: #f5e0a3;
filter: drop-shadow(0 0 2vmin #fcf1cf);
height: calc(var(--size) * 0.25);
aspect-ratio: 1;
overflow: visible !important;
bottom: 100%;
left: 50%;
transform: translate(-50%, 0);
position: absolute;
stroke-dasharray: 1000 1000;
fill: none;
animation: stroke 1s calc(var(--star-delay) * 1s) both;
}
@keyframes stroke {
from {
stroke-dashoffset: -1000;
}
}
.tree__bauble:after, .tree__bauble:before {
content: "";
height: calc(var(--size) * 0.065);
position: absolute;
aspect-ratio: 1;
background: hsl(var(--hue, 10) 98% 80%);
box-shadow: 0 0 calc(var(--size) * 0.2) hsl(var(--hue, 10) 98% 40%);
border-radius: 50%;
top: 50%;
left: 50%;
animation: reveal calc(var(--reveal) * 1s) calc(var(--reveal-delay, 2s) + ((10 - var(--index)) * 0.125s)) both;
transform:
translate(-50%, -50%)
rotateY(var(--r, 0deg))
translateZ(calc((-4px + (var(--size) * (var(--index) / 10)) * -0.5)));
}
.tree__bauble:before {
--r: 180deg;
}
@xkeshav
Copy link
Author

xkeshav commented Dec 25, 2022

Superb for inspiration

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment