The tower arm swings clear, an accent-tipped rocket lifts off its pad on a growing flame, then comes back down tail first and settles on its legs in a puff of hairline smoke.
Also known as: rocket launch animation, isometric rocket, hairline animation.
<div class="hln-rocket-launch" role="img" aria-label="A rocket lifts off its pad and lands back on it"><svg viewBox="-66 -45 132 72" aria-hidden="true"><g><polygon points="-36,18 0,36 0,33 -36,15"/><polygon points="36,18 0,36 0,33 36,15"/><polygon points="0,-3 36,15 0,33 -36,15"/></g><polygon class="hln-rocket-launch-l" points="0,0 30,15 0,30 -30,15"/><g><polygon points="-8,5 -2,8 -2,-32 -8,-35"/><polygon points="4,5 -2,8 -2,-32 4,-35"/><polygon points="-2,-38 4,-35 -2,-32 -8,-35"/></g><line x1="-8" y1="-1" x2="-2" y2="-4" class="hln-rocket-launch-l"/><line x1="4" y1="-1" x2="-2" y2="-4" class="hln-rocket-launch-l"/><line x1="-8" y1="-7" x2="-2" y2="-10" class="hln-rocket-launch-l"/><line x1="4" y1="-7" x2="-2" y2="-10" class="hln-rocket-launch-l"/><line x1="-8" y1="-13" x2="-2" y2="-16" class="hln-rocket-launch-l"/><line x1="4" y1="-13" x2="-2" y2="-16" class="hln-rocket-launch-l"/><line x1="-8" y1="-19" x2="-2" y2="-22" class="hln-rocket-launch-l"/><line x1="4" y1="-19" x2="-2" y2="-22" class="hln-rocket-launch-l"/><line x1="-8" y1="-25" x2="-2" y2="-28" class="hln-rocket-launch-l"/><line x1="4" y1="-25" x2="-2" y2="-28" class="hln-rocket-launch-l"/><line x1="-8" y1="-31" x2="-2" y2="-32" class="hln-rocket-launch-l"/><line x1="4" y1="-31" x2="-2" y2="-32" class="hln-rocket-launch-l"/><g class="hln-rocket-launch-arm"><g><polygon points="0,-21 5,-18.5 5,-20 0,-22.5"/><polygon points="7,-19.5 5,-18.5 5,-20 7,-21"/><polygon points="2,-23.5 7,-21 5,-20 0,-22.5"/></g></g><g><polygon points="-12,15 0,21 0,18 -12,12"/><polygon points="12,15 0,21 0,18 12,12"/><polygon points="0,6 12,12 0,18 -12,12"/></g><g class="hln-rocket-launch-puff" style="--delay: 0s"><ellipse cx="-4" cy="7" rx="4.24" ry="2.12" class="hln-rocket-launch-l"/></g><g class="hln-rocket-launch-puff" style="--delay: -0.1s"><ellipse cx="5" cy="6.5" rx="3.68" ry="1.84" class="hln-rocket-launch-l"/></g><g class="hln-rocket-launch-fly"><g class="hln-rocket-launch-flame"><path class="hln-rocket-launch-a" d="M-3.6,12 C-3.6,18 -1,22 0,28 C1,22 3.6,18 3.6,12 Z"/><path class="hln-rocket-launch-l" fill="none" d="M-1.4,13 C-1.2,17 -0.4,19 0,22 C0.4,19 1.2,17 1.4,13"/></g><polygon points="-3,10.5 -8,8 -3,1.5"/><polygon points="3,10.5 8,8 3,1.5"/><path d="M-4.95,-20 L-4.95,12 A4.95,2.47 0 0 0 4.95,12 L4.95,-20 Z"/><ellipse cx="0" cy="-20" rx="4.95" ry="2.47"/><path d="M-4.95,-12 A4.95,2.47 0 0 0 4.95,-12" fill="none" class="hln-rocket-launch-l"/><path d="M-4.95,6 A4.95,2.47 0 0 0 4.95,6" fill="none" class="hln-rocket-launch-l"/><path d="M-0.01,-30 L-4.95,-20 A4.95,2.47 0 0 0 4.95,-20 L0.01,-30 Z" class="hln-rocket-launch-a"/><ellipse cx="0" cy="-30" rx="0.01" ry="0.01" class="hln-rocket-launch-a"/><path d="M-4.95,-20 A4.95,2.47 0 0 0 4.95,-20" fill="none"/><polygon points="3,13.5 8,16 3,4.5"/><polygon points="-3,13.5 -8,16 -3,4.5"/></g><g class="hln-rocket-launch-puff" style="--delay: -0.05s"><ellipse cx="4" cy="16" rx="4.53" ry="2.26" class="hln-rocket-launch-l"/></g><g class="hln-rocket-launch-puff" style="--delay: -0.15s"><ellipse cx="-6" cy="16" rx="4.81" ry="2.4" class="hln-rocket-launch-l"/></g><g class="hln-rocket-launch-puff" style="--delay: -0.2s"><ellipse cx="0" cy="19" rx="3.39" ry="1.7" class="hln-rocket-launch-l"/></g></svg></div>
.hln-rocket-launch {
--c: var(--hln-color, #ff4f2e);
font-size: var(--hln-size, 16px);
position: relative;
display: grid;
place-items: center;
width: 22em;
height: 12em;
border-radius: 0.75em;
background: #f6f5f1;
overflow: hidden;
--u: 1px;
}
.hln-rocket-launch svg {
width: 100%;
height: 100%;
overflow: visible;
fill: #ffffff;
stroke: #1c1d21;
stroke-width: 1.25;
stroke-linejoin: round;
stroke-linecap: round;
}
.hln-rocket-launch svg * {
vector-effect: non-scaling-stroke;
}
.hln-rocket-launch-l {
stroke: #9a9ca3;
}
.hln-rocket-launch-a {
fill: var(--c);
}
.hln-rocket-launch-fly {
animation: hln-rocket-launch-fly 8s linear infinite;
}
.hln-rocket-launch-flame {
transform-box: fill-box;
transform-origin: 50% 0;
animation: hln-rocket-launch-flame 8s linear infinite;
}
.hln-rocket-launch-arm {
animation: hln-rocket-launch-arm 8s linear infinite;
}
.hln-rocket-launch-puff {
transform-box: fill-box;
transform-origin: 50% 50%;
animation: hln-rocket-launch-puff 8s linear infinite;
animation-delay: var(--delay);
}
@keyframes hln-rocket-launch-fly {
0%, 24% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); animation-timing-function: cubic-bezier(.55, 0, .85, .3); }
46% { transform: translate(calc(var(--u) * 0), calc(var(--u) * -150)); }
58% { transform: translate(calc(var(--u) * 0), calc(var(--u) * -150)); animation-timing-function: cubic-bezier(.15, .6, .3, 1); }
80% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); animation-timing-function: ease-out; }
81.5% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0.6)); animation-timing-function: cubic-bezier(.3, 1.45, .5, 1); }
86%, 100% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); }
}
@keyframes hln-rocket-launch-flame {
0%, 21% { transform: scaleY(0); animation-timing-function: cubic-bezier(.3, 1.45, .5, 1); }
26% { transform: scaleY(1); }
40% { transform: scaleY(1.3); }
58% { transform: scaleY(1.3); }
78% { transform: scaleY(0.8); animation-timing-function: ease-in; }
84%, 100% { transform: scaleY(0); }
}
@keyframes hln-rocket-launch-arm {
0%, 8% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
16%, 86% { transform: translate(calc(var(--u) * -5), calc(var(--u) * -2.5)); animation-timing-function: cubic-bezier(.3, 1.45, .5, 1); }
94%, 100% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); }
}
@keyframes hln-rocket-launch-puff {
0%, 20% { transform: scale(0); opacity: 1; animation-timing-function: cubic-bezier(.22, 1, .36, 1); }
36% { transform: scale(1.6); opacity: 1; animation-timing-function: ease-in; }
44% { transform: scale(1.8); opacity: 0; }
45%, 74% { transform: scale(0); opacity: 1; animation-timing-function: cubic-bezier(.22, 1, .36, 1); }
86% { transform: scale(1.3); opacity: 1; animation-timing-function: ease-in; }
94%, 100% { transform: scale(1.5); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
.hln-rocket-launch * {
animation-play-state: paused !important;
animation-delay: calc(var(--delay, 0s) - 0.5s) !important;
}
}
@media (prefers-reduced-motion: reduce) {
.hln-rocket-launch, .hln-rocket-launch *, .hln-rocket-launch::before, .hln-rocket-launch::after, .hln-rocket-launch *::before, .hln-rocket-launch *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}--hln-color on the element or a parent.
Currently previewing #3b82f6.--hln-size. Every other dimension is in
em, so the whole thing scales together. Currently previewing 16px.transition or animation
shorthand. Staggered delays are relative, so they keep their rhythm.