A rocket that rumbles on its pad, lifts off on a flickering flame and hovers while checked, as three smoke puffs roll out below. Unchecking lands it again. Made for ship and deploy tasks.
Also known as: rocket animation css, launch checkbox, deploy checkbox animation.
<label class="chk-rocket-launch">
<input type="checkbox">
<span class="chk-rocket-launch-pad" aria-hidden="true">
<i class="chk-rocket-launch-smoke"></i><i class="chk-rocket-launch-smoke"></i><i class="chk-rocket-launch-smoke"></i>
<span class="chk-rocket-launch-craft">
<i class="chk-rocket-launch-flame"></i>
<svg viewBox="0 0 24 24"><path class="chk-rocket-launch-body" d="M12 2.5c3 2.2 4.5 5.6 4.5 9.6v4.4h-9v-4.4c0-4 1.5-7.4 4.5-9.6z"/><path d="M7.5 12.5 5 15.5v3l2.5-1.5M16.5 12.5l2.5 3v3l-2.5-1.5"/><circle class="chk-rocket-launch-window" cx="12" cy="9.5" r="1.7"/></svg>
</span>
</span>
<span class="chk-rocket-launch-text">Ship the release</span>
</label>.chk-rocket-launch {
--c: var(--chk-color, #3b82f6);
font-size: var(--chk-size, 24px);
position: relative;
display: inline-flex;
align-items: center;
gap: 0.6em;
line-height: 1.3;
cursor: pointer;
-webkit-user-select: none;
user-select: none;
-webkit-tap-highlight-color: transparent;
gap: 0.55em;}
.chk-rocket-launch input {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
margin: 0;
opacity: 0;
cursor: pointer;
z-index: 1;
}
.chk-rocket-launch-pad {
position: relative;
flex: none;
width: 1.9em;
height: 2.4em;
border-radius: 0.3em;
}
.chk-rocket-launch-pad::after {
content: "";
position: absolute;
left: 15%;
right: 15%;
bottom: 0.1em;
height: 0.08em;
border-radius: 1em;
background: color-mix(in srgb, currentColor 25%, transparent);
}
.chk-rocket-launch-craft {
position: absolute;
left: 50%;
bottom: 0.2em;
width: 1.65em;
height: 1.65em;
margin-left: -0.825em;
transform: translate(0, 0);
transition: transform 0.4s ease-in;
}
.chk-rocket-launch-craft svg {
position: relative;
width: 100%;
height: 100%;
color: color-mix(in srgb, currentColor 70%, transparent);
fill: none;
stroke: currentColor;
stroke-width: 1.6;
stroke-linecap: round;
stroke-linejoin: round;
transition: color 0.25s ease;
}
.chk-rocket-launch-body {
fill: transparent;
transition: fill 0.25s ease;
}
.chk-rocket-launch-window {
fill: transparent;
transition: fill 0.25s ease;
}
.chk-rocket-launch-flame {
position: absolute;
left: 50%;
top: 64%;
width: 0.4em;
height: 0.6em;
margin-left: -0.2em;
border-radius: 50% 50% 50% 50% / 30% 30% 70% 70%;
background: linear-gradient(#fde68a, #f97316);
transform-origin: 50% 0;
transform: scaleY(0);
transition: transform 0.15s ease-in;
}
.chk-rocket-launch-smoke {
position: absolute;
bottom: 0.05em;
left: 50%;
width: 0.4em;
height: 0.4em;
margin-left: -0.2em;
border-radius: 50%;
background: color-mix(in srgb, currentColor 22%, transparent);
transform: translateX(0) scale(0);
}
.chk-rocket-launch-text {
transition: color 0.25s ease;
}
.chk-rocket-launch:hover .chk-rocket-launch-craft svg {
color: var(--c);
}
.chk-rocket-launch input:checked + .chk-rocket-launch-pad .chk-rocket-launch-craft {
transform: translate(0, -0.45em);
animation: chk-rocket-launch-lift 0.7s ease-in, chk-rocket-launch-hover 1.6s ease-in-out 0.7s infinite alternate;
}
.chk-rocket-launch input:checked + .chk-rocket-launch-pad .chk-rocket-launch-craft svg {
color: var(--c);
}
.chk-rocket-launch input:checked + .chk-rocket-launch-pad .chk-rocket-launch-body {
fill: var(--c);
}
.chk-rocket-launch input:checked + .chk-rocket-launch-pad .chk-rocket-launch-window {
fill: #fff;
}
.chk-rocket-launch input:checked + .chk-rocket-launch-pad .chk-rocket-launch-flame {
transform: scaleY(1);
transition: transform 0.2s ease-out 0.25s;
animation: chk-rocket-launch-flicker 0.14s ease-in-out 0.45s infinite alternate;
}
.chk-rocket-launch input:checked + .chk-rocket-launch-pad .chk-rocket-launch-smoke {
--x: -0.45em;
animation: chk-rocket-launch-puff 0.8s ease-out 0.3s both;
}
.chk-rocket-launch input:checked + .chk-rocket-launch-pad .chk-rocket-launch-smoke + .chk-rocket-launch-smoke {
--x: 0em;
animation-delay: 0.35s;
}
.chk-rocket-launch input:checked + .chk-rocket-launch-pad .chk-rocket-launch-smoke + .chk-rocket-launch-smoke + .chk-rocket-launch-smoke {
--x: 0.45em;
animation-delay: 0.4s;
}
.chk-rocket-launch input:checked ~ .chk-rocket-launch-text {
color: var(--c);
}
.chk-rocket-launch input:focus-visible + .chk-rocket-launch-pad {
outline: 0.12em solid var(--c);
outline-offset: 0.18em;
}
@keyframes chk-rocket-launch-lift {
0% { transform: translate(0, 0); }
8% { transform: translate(-0.03em, 0); }
16% { transform: translate(0.03em, 0); }
24% { transform: translate(-0.03em, 0); }
32% { transform: translate(0.03em, 0); }
40% { transform: translate(0, 0); }
100% { transform: translate(0, -0.45em); }
}
@keyframes chk-rocket-launch-hover {
from { transform: translate(0, -0.45em); }
to { transform: translate(0, -0.33em); }
}
@keyframes chk-rocket-launch-flicker {
from { transform: scaleY(1) scaleX(1); }
to { transform: scaleY(0.72) scaleX(0.85); }
}
@keyframes chk-rocket-launch-puff {
0% { opacity: 1; transform: translateX(0) scale(0); }
50% { opacity: 1; transform: translateX(calc(var(--x) * 0.7)) scale(1); }
100% { opacity: 0; transform: translateX(var(--x)) scale(1.3); }
}
@media (prefers-reduced-motion: reduce) {
.chk-rocket-launch, .chk-rocket-launch *, .chk-rocket-launch::before, .chk-rocket-launch::after, .chk-rocket-launch *::before, .chk-rocket-launch *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}--chk-color on the element or a parent.
Currently previewing #3b82f6.--chk-size. Every other dimension is in
em, so the whole thing scales together. Currently previewing 24px.transition or animation
shorthand. Staggered delays are relative, so they keep their rhythm.