Three Dancing Kittens
Three tiny kittens in cream, grey, and peach doing the same synchronized dance pose with a bouncing music note and wagging tails. Inspired by the viral TikTok trend of three AI-generated kittens dancing in sync.
← you, in 30 minutes.
what you'll build
Here's the plan
Three tiny kittens in cream, grey, and peach doing the same synchronized dance pose, with a bouncing sky-blue music note and twinkling gold sparkles. The whole trio bounces together on one loop while tails wag and eyes blink, keeping every face, paw, and ear in perfect sync.
You’ll learn
- Reusing one kitten function to draw three characters with different colors and positions
- Animating a parent group so every child moves together without separate per-part keyframes
- Combining translateY bounces with tail rotation for a playful but coherent dance
- Animating tails from their base so they wag instead of spinning
- Skill level
- Beginner
- Time
- ~30 min
- Tools
- Just a browser
- Code type
- SVG + CSS
- Lines
- ~142
the steps
Build it, one change at a time
Set the stage
Warm paper background, a floating music note made from a path and two small circles, and four sparkles. The note will bounce later, so keep it in its own group.
<rect x="0" y="0" width="200" height="200" rx="18" fill="#FBF2E5" stroke="none"/> <g class="tk-music" fill="#6FA8FF" stroke="#2B3A55" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"> <path d="M156 44 C156 38 160 34 166 34 C172 34 176 38 176 44 C176 50 172 54 166 54 C164 54 162 53 160 52 L156 60 L156 52 C154 50 154 46 156 44 Z"/> <circle cx="150" cy="58" r="2.8" fill="#6FA8FF" stroke="none"/> <circle cx="142" cy="50" r="2.2" fill="#6FA8FF" stroke="none"/> </g> <path class="tk-spark tk-spark1" d="M36 54 L40 62 L36 70 L32 62 Z" fill="#FFD84D" stroke="#2B3A55" stroke-width="1.8" stroke-linejoin="round"/> <path class="tk-spark tk-spark2" d="M170 92 L173 98 L170 104 L167 98 Z" fill="#FF8FA3" stroke="none"/> <circle class="tk-spark tk-dot1" cx="52" cy="36" r="2.6" fill="#FFD84D" stroke="none"/> <circle class="tk-spark tk-dot2" cx="176" cy="124" r="2.2" fill="#6FA8FF" stroke="none"/>a stage, a beat, and some sparkles.
Build the kitten trio
Use a small helper to draw each kitten: a curved tail, an oval body, a belly patch, two legs, one raised paw and one lowered paw, a round head, and two pointy ears with pink insides. Call it three times with different x positions and fur colors.
function kitten(x, color) { return `<g transform="translate(${x - 55}, 0)"> <path class="tk-tail" d="M38 124 C28 118 28 106 36 102" fill="none" stroke="#2B3A55" stroke-width="3" stroke-linecap="round"/> <ellipse class="tk-body" cx="55" cy="120" rx="26" ry="32" fill="${color}" stroke="#2B3A55" stroke-width="3"/> <ellipse class="tk-belly" cx="55" cy="128" rx="14" ry="18" fill="#FFFDF7" opacity="0.7" stroke="none"/> <ellipse class="tk-leg tk-leg-l" cx="42" cy="150" rx="7" ry="10" fill="${color}" stroke="#2B3A55" stroke-width="3"/> <ellipse class="tk-leg tk-leg-r" cx="68" cy="150" rx="7" ry="10" fill="${color}" stroke="#2B3A55" stroke-width="3"/> <ellipse class="tk-paw tk-paw-l" cx="36" cy="100" rx="7" ry="6" fill="${color}" stroke="#2B3A55" stroke-width="3"/> <ellipse class="tk-paw tk-paw-r" cx="74" cy="132" rx="7" ry="6" fill="${color}" stroke="#2B3A55" stroke-width="3"/> <circle class="tk-head" cx="55" cy="82" r="24" fill="${color}" stroke="#2B3A55" stroke-width="3"/> <path class="tk-ear tk-ear-l" d="M34 68 L30 50 L48 62 Z" fill="${color}" stroke="#2B3A55" stroke-width="3" stroke-linejoin="round"/> <path class="tk-ear tk-ear-r" d="M76 68 L80 50 L62 62 Z" fill="${color}" stroke="#2B3A55" stroke-width="3" stroke-linejoin="round"/> <path d="M36 64 L33 54 L45 62 Z" fill="#FF8FA3" stroke="none"/> <path d="M74 64 L77 54 L65 62 Z" fill="#FF8FA3" stroke="none"/> </g>`; } <g class="tk-trio"> ${kitten(55, "#FFFDF7")} ${kitten(100, "#D4D4D4")} ${kitten(145, "#FFE8E6")} </g>three faceless dancers — color does most of the work.
Add faces and whiskers
Each kitten gets sleepy navy eyes with white shines, a pink nose, a tiny smile, coral blush spots, and a few whisker lines. Keep the face group inside the same transform so it rides along with each kitten.
<g class="tk-face" transform="translate(0, 0)"> <circle class="tk-eye tk-eye-l" cx="47" cy="80" r="4.5" fill="#2B3A55" stroke="none"/> <circle class="tk-eye tk-eye-r" cx="63" cy="80" r="4.5" fill="#2B3A55" stroke="none"/> <circle class="tk-shine tk-shine-l" cx="48.5" cy="78.5" r="1.6" fill="#FFFDF7" stroke="none"/> <circle class="tk-shine tk-shine-r" cx="64.5" cy="78.5" r="1.6" fill="#FFFDF7" stroke="none"/> <ellipse class="tk-nose" cx="55" cy="86" rx="3" ry="2.2" fill="#FF8FA3" stroke="none"/> <path d="M55 88 Q55 92 51 92" fill="none" stroke="#2B3A55" stroke-width="1.6" stroke-linecap="round"/> <path d="M55 88 Q55 92 59 92" fill="none" stroke="#2B3A55" stroke-width="1.6" stroke-linecap="round"/> <ellipse cx="40" cy="86" rx="4" ry="2.6" fill="#FF8FA3" opacity="0.6" stroke="none"/> <ellipse cx="70" cy="86" rx="4" ry="2.6" fill="#FF8FA3" opacity="0.6" stroke="none"/> <path d="M28 82 Q22 84 26 88" fill="none" stroke="#2B3A55" stroke-width="1.4" stroke-linecap="round" opacity="0.5"/> <path d="M82 82 Q88 84 84 88" fill="none" stroke="#2B3A55" stroke-width="1.4" stroke-linecap="round" opacity="0.5"/> </g>three sleepy kittens ready to dance.
Make them dance in sync
Animate the whole trio group with one translateY bounce so every kitten, paw, and face rises and falls together. The tails wag from their base on the same loop, the music note bounces, and the sparkles twinkle — all inside a prefers-reduced-motion guard.
@media (prefers-reduced-motion: no-preference) { .tk .tk-trio { transform-box: fill-box; transform-origin: center bottom; animation: tk-dance 1.6s ease-in-out infinite; } .tk .tk-tail { transform-box: fill-box; transform-origin: 100% 100%; animation: tk-tail-wag 1.6s ease-in-out infinite; } .tk .tk-music { transform-box: fill-box; transform-origin: center; animation: tk-note-bounce 2.2s ease-in-out infinite; } .tk .tk-spark1 { animation: tk-twinkle 2.8s ease-in-out infinite; } .tk .tk-spark2 { animation: tk-twinkle 2.8s ease-in-out 0.6s infinite; } .tk .tk-dot1 { animation: tk-twinkle 3.2s ease-in-out 1.2s infinite; } .tk .tk-dot2 { animation: tk-twinkle 3.2s ease-in-out 1.8s infinite; } .tk .tk-shine { animation: tk-blink 3.4s ease-in-out infinite; } } @keyframes tk-dance { 0%, 100% { transform: translateY(0); } 25% { transform: translateY(-6px); } 50% { transform: translateY(0); } 75% { transform: translateY(-4px); } } @keyframes tk-tail-wag { 0%, 100% { transform: rotate(0deg); } 25% { transform: rotate(8deg); } 75% { transform: rotate(-6deg); } } @keyframes tk-note-bounce { 0%, 100% { transform: translateY(0) rotate(0deg); } 50% { transform: translateY(-4px) rotate(4deg); } } @keyframes tk-twinkle { 0%, 100% { opacity: 0.34; transform: scale(0.84); } 45% { opacity: 1; transform: scale(1.14); } } @keyframes tk-blink { 0%, 44%, 56%, 100% { opacity: 1; } 50% { opacity: 0.25; } }three kittens, one beat, infinite loop.
the complete code
Everything, in one place
Skipped straight to the end? Welcome. Copy the whole thing, download it, or open it in the Playground to start remixing.
<svg class="tk" viewBox="0 0 200 200" width="200" height="200" role="img" aria-label="Three cute kittens dancing in sync with a bouncing music note, twinkling sparkles, and wagging tails">
<rect x="0" y="0" width="200" height="200" rx="18" fill="#FBF2E5" stroke="none"/>
<g class="tk-music" fill="#6FA8FF" stroke="#2B3A55" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
<path d="M156 44 C156 38 160 34 166 34 C172 34 176 38 176 44 C176 50 172 54 166 54 C164 54 162 53 160 52 L156 60 L156 52 C154 50 154 46 156 44 Z"/>
<circle cx="150" cy="58" r="2.8" fill="#6FA8FF" stroke="none"/>
<circle cx="142" cy="50" r="2.2" fill="#6FA8FF" stroke="none"/>
</g>
<path class="tk-spark tk-spark1" d="M36 54 L40 62 L36 70 L32 62 Z" fill="#FFD84D" stroke="#2B3A55" stroke-width="1.8" stroke-linejoin="round"/>
<path class="tk-spark tk-spark2" d="M170 92 L173 98 L170 104 L167 98 Z" fill="#FF8FA3" stroke="none"/>
<circle class="tk-spark tk-dot1" cx="52" cy="36" r="2.6" fill="#FFD84D" stroke="none"/>
<circle class="tk-spark tk-dot2" cx="176" cy="124" r="2.2" fill="#6FA8FF" stroke="none"/>
<g class="tk-trio" stroke-linecap="round" stroke-linejoin="round">
<g class="tk-kitten tk-k1" transform="translate(0, 0)">
<!-- Tail -->
<path class="tk-tail" d="M38 124 C28 118 28 106 36 102" fill="none" stroke="#2B3A55" stroke-width="3" stroke-linecap="round"/>
<!-- Body -->
<ellipse class="tk-body" cx="55" cy="120" rx="26" ry="32" fill="#FFFDF7" stroke="#2B3A55" stroke-width="3"/>
<!-- Belly patch -->
<ellipse class="tk-belly" cx="55" cy="128" rx="14" ry="18" fill="#FFFDF7" opacity="0.7" stroke="none"/>
<!-- Legs -->
<ellipse class="tk-leg tk-leg-l" cx="42" cy="150" rx="7" ry="10" fill="#FFFDF7" stroke="#2B3A55" stroke-width="3"/>
<ellipse class="tk-leg tk-leg-r" cx="68" cy="150" rx="7" ry="10" fill="#FFFDF7" stroke="#2B3A55" stroke-width="3"/>
<!-- Paws (one raised) -->
<ellipse class="tk-paw tk-paw-l" cx="36" cy="100" rx="7" ry="6" fill="#FFFDF7" stroke="#2B3A55" stroke-width="3"/>
<ellipse class="tk-paw tk-paw-r" cx="74" cy="132" rx="7" ry="6" fill="#FFFDF7" stroke="#2B3A55" stroke-width="3"/>
<!-- Head -->
<circle class="tk-head" cx="55" cy="82" r="24" fill="#FFFDF7" stroke="#2B3A55" stroke-width="3"/>
<!-- Ears -->
<path class="tk-ear tk-ear-l" d="M34 68 L30 50 L48 62 Z" fill="#FFFDF7" stroke="#2B3A55" stroke-width="3" stroke-linejoin="round"/>
<path class="tk-ear tk-ear-r" d="M76 68 L80 50 L62 62 Z" fill="#FFFDF7" stroke="#2B3A55" stroke-width="3" stroke-linejoin="round"/>
<path d="M36 64 L33 54 L45 62 Z" fill="#FF8FA3" stroke="none"/>
<path d="M74 64 L77 54 L65 62 Z" fill="#FF8FA3" stroke="none"/>
</g>
<g class="tk-kitten tk-k2" transform="translate(45, 0)">
<!-- Tail -->
<path class="tk-tail" d="M38 124 C28 118 28 106 36 102" fill="none" stroke="#2B3A55" stroke-width="3" stroke-linecap="round"/>
<!-- Body -->
<ellipse class="tk-body" cx="55" cy="120" rx="26" ry="32" fill="#D4D4D4" stroke="#2B3A55" stroke-width="3"/>
<!-- Belly patch -->
<ellipse class="tk-belly" cx="55" cy="128" rx="14" ry="18" fill="#FFFDF7" opacity="0.7" stroke="none"/>
<!-- Legs -->
<ellipse class="tk-leg tk-leg-l" cx="42" cy="150" rx="7" ry="10" fill="#D4D4D4" stroke="#2B3A55" stroke-width="3"/>
<ellipse class="tk-leg tk-leg-r" cx="68" cy="150" rx="7" ry="10" fill="#D4D4D4" stroke="#2B3A55" stroke-width="3"/>
<!-- Paws (one raised) -->
<ellipse class="tk-paw tk-paw-l" cx="36" cy="100" rx="7" ry="6" fill="#D4D4D4" stroke="#2B3A55" stroke-width="3"/>
<ellipse class="tk-paw tk-paw-r" cx="74" cy="132" rx="7" ry="6" fill="#D4D4D4" stroke="#2B3A55" stroke-width="3"/>
<!-- Head -->
<circle class="tk-head" cx="55" cy="82" r="24" fill="#D4D4D4" stroke="#2B3A55" stroke-width="3"/>
<!-- Ears -->
<path class="tk-ear tk-ear-l" d="M34 68 L30 50 L48 62 Z" fill="#D4D4D4" stroke="#2B3A55" stroke-width="3" stroke-linejoin="round"/>
<path class="tk-ear tk-ear-r" d="M76 68 L80 50 L62 62 Z" fill="#D4D4D4" stroke="#2B3A55" stroke-width="3" stroke-linejoin="round"/>
<path d="M36 64 L33 54 L45 62 Z" fill="#FF8FA3" stroke="none"/>
<path d="M74 64 L77 54 L65 62 Z" fill="#FF8FA3" stroke="none"/>
</g>
<g class="tk-kitten tk-k3" transform="translate(90, 0)">
<!-- Tail -->
<path class="tk-tail" d="M38 124 C28 118 28 106 36 102" fill="none" stroke="#2B3A55" stroke-width="3" stroke-linecap="round"/>
<!-- Body -->
<ellipse class="tk-body" cx="55" cy="120" rx="26" ry="32" fill="#FFE8E6" stroke="#2B3A55" stroke-width="3"/>
<!-- Belly patch -->
<ellipse class="tk-belly" cx="55" cy="128" rx="14" ry="18" fill="#FFFDF7" opacity="0.7" stroke="none"/>
<!-- Legs -->
<ellipse class="tk-leg tk-leg-l" cx="42" cy="150" rx="7" ry="10" fill="#FFE8E6" stroke="#2B3A55" stroke-width="3"/>
<ellipse class="tk-leg tk-leg-r" cx="68" cy="150" rx="7" ry="10" fill="#FFE8E6" stroke="#2B3A55" stroke-width="3"/>
<!-- Paws (one raised) -->
<ellipse class="tk-paw tk-paw-l" cx="36" cy="100" rx="7" ry="6" fill="#FFE8E6" stroke="#2B3A55" stroke-width="3"/>
<ellipse class="tk-paw tk-paw-r" cx="74" cy="132" rx="7" ry="6" fill="#FFE8E6" stroke="#2B3A55" stroke-width="3"/>
<!-- Head -->
<circle class="tk-head" cx="55" cy="82" r="24" fill="#FFE8E6" stroke="#2B3A55" stroke-width="3"/>
<!-- Ears -->
<path class="tk-ear tk-ear-l" d="M34 68 L30 50 L48 62 Z" fill="#FFE8E6" stroke="#2B3A55" stroke-width="3" stroke-linejoin="round"/>
<path class="tk-ear tk-ear-r" d="M76 68 L80 50 L62 62 Z" fill="#FFE8E6" stroke="#2B3A55" stroke-width="3" stroke-linejoin="round"/>
<path d="M36 64 L33 54 L45 62 Z" fill="#FF8FA3" stroke="none"/>
<path d="M74 64 L77 54 L65 62 Z" fill="#FF8FA3" stroke="none"/>
</g>
<g class="tk-face" transform="translate(0, 0)">
<circle class="tk-eye tk-eye-l" cx="47" cy="80" r="4.5" fill="#2B3A55" stroke="none"/>
<circle class="tk-eye tk-eye-r" cx="63" cy="80" r="4.5" fill="#2B3A55" stroke="none"/>
<circle class="tk-shine tk-shine-l" cx="48.5" cy="78.5" r="1.6" fill="#FFFDF7" stroke="none"/>
<circle class="tk-shine tk-shine-r" cx="64.5" cy="78.5" r="1.6" fill="#FFFDF7" stroke="none"/>
<ellipse class="tk-nose" cx="55" cy="86" rx="3" ry="2.2" fill="#FF8FA3" stroke="none"/>
<path d="M55 88 Q55 92 51 92" fill="none" stroke="#2B3A55" stroke-width="1.6" stroke-linecap="round"/>
<path d="M55 88 Q55 92 59 92" fill="none" stroke="#2B3A55" stroke-width="1.6" stroke-linecap="round"/>
<ellipse cx="40" cy="86" rx="4" ry="2.6" fill="#FF8FA3" opacity="0.6" stroke="none"/>
<ellipse cx="70" cy="86" rx="4" ry="2.6" fill="#FF8FA3" opacity="0.6" stroke="none"/>
<path d="M28 82 Q22 84 26 88" fill="none" stroke="#2B3A55" stroke-width="1.4" stroke-linecap="round" opacity="0.5"/>
<path d="M30 86 Q24 88 28 92" fill="none" stroke="#2B3A55" stroke-width="1.4" stroke-linecap="round" opacity="0.5"/>
<path d="M82 82 Q88 84 84 88" fill="none" stroke="#2B3A55" stroke-width="1.4" stroke-linecap="round" opacity="0.5"/>
<path d="M80 86 Q86 88 82 92" fill="none" stroke="#2B3A55" stroke-width="1.4" stroke-linecap="round" opacity="0.5"/>
</g>
<g class="tk-face" transform="translate(45, 0)">
<circle class="tk-eye tk-eye-l" cx="47" cy="80" r="4.5" fill="#2B3A55" stroke="none"/>
<circle class="tk-eye tk-eye-r" cx="63" cy="80" r="4.5" fill="#2B3A55" stroke="none"/>
<circle class="tk-shine tk-shine-l" cx="48.5" cy="78.5" r="1.6" fill="#FFFDF7" stroke="none"/>
<circle class="tk-shine tk-shine-r" cx="64.5" cy="78.5" r="1.6" fill="#FFFDF7" stroke="none"/>
<ellipse class="tk-nose" cx="55" cy="86" rx="3" ry="2.2" fill="#FF8FA3" stroke="none"/>
<path d="M55 88 Q55 92 51 92" fill="none" stroke="#2B3A55" stroke-width="1.6" stroke-linecap="round"/>
<path d="M55 88 Q55 92 59 92" fill="none" stroke="#2B3A55" stroke-width="1.6" stroke-linecap="round"/>
<ellipse cx="40" cy="86" rx="4" ry="2.6" fill="#FF8FA3" opacity="0.6" stroke="none"/>
<ellipse cx="70" cy="86" rx="4" ry="2.6" fill="#FF8FA3" opacity="0.6" stroke="none"/>
<path d="M28 82 Q22 84 26 88" fill="none" stroke="#2B3A55" stroke-width="1.4" stroke-linecap="round" opacity="0.5"/>
<path d="M30 86 Q24 88 28 92" fill="none" stroke="#2B3A55" stroke-width="1.4" stroke-linecap="round" opacity="0.5"/>
<path d="M82 82 Q88 84 84 88" fill="none" stroke="#2B3A55" stroke-width="1.4" stroke-linecap="round" opacity="0.5"/>
<path d="M80 86 Q86 88 82 92" fill="none" stroke="#2B3A55" stroke-width="1.4" stroke-linecap="round" opacity="0.5"/>
</g>
<g class="tk-face" transform="translate(90, 0)">
<circle class="tk-eye tk-eye-l" cx="47" cy="80" r="4.5" fill="#2B3A55" stroke="none"/>
<circle class="tk-eye tk-eye-r" cx="63" cy="80" r="4.5" fill="#2B3A55" stroke="none"/>
<circle class="tk-shine tk-shine-l" cx="48.5" cy="78.5" r="1.6" fill="#FFFDF7" stroke="none"/>
<circle class="tk-shine tk-shine-r" cx="64.5" cy="78.5" r="1.6" fill="#FFFDF7" stroke="none"/>
<ellipse class="tk-nose" cx="55" cy="86" rx="3" ry="2.2" fill="#FF8FA3" stroke="none"/>
<path d="M55 88 Q55 92 51 92" fill="none" stroke="#2B3A55" stroke-width="1.6" stroke-linecap="round"/>
<path d="M55 88 Q55 92 59 92" fill="none" stroke="#2B3A55" stroke-width="1.6" stroke-linecap="round"/>
<ellipse cx="40" cy="86" rx="4" ry="2.6" fill="#FF8FA3" opacity="0.6" stroke="none"/>
<ellipse cx="70" cy="86" rx="4" ry="2.6" fill="#FF8FA3" opacity="0.6" stroke="none"/>
<path d="M28 82 Q22 84 26 88" fill="none" stroke="#2B3A55" stroke-width="1.4" stroke-linecap="round" opacity="0.5"/>
<path d="M30 86 Q24 88 28 92" fill="none" stroke="#2B3A55" stroke-width="1.4" stroke-linecap="round" opacity="0.5"/>
<path d="M82 82 Q88 84 84 88" fill="none" stroke="#2B3A55" stroke-width="1.4" stroke-linecap="round" opacity="0.5"/>
<path d="M80 86 Q86 88 82 92" fill="none" stroke="#2B3A55" stroke-width="1.4" stroke-linecap="round" opacity="0.5"/>
</g>
</g>
</svg>
tips & gotchas
Mistakes we actually made
Draw each kitten as a reusable function or group; changing color and x position is much faster than copy-pasting three whole bodies.
Animate the parent group when every part needs to move together; per-child bobs look lively only if faces and bodies share the same transform.
Tail wag origin should be at the tail's base (100% 100% in the kitten's local space) so it arcs naturally.
Keep the trio's shared dance loop short (1.6s) and the music-note loop slightly longer (2.2s) so the bounce never feels perfectly aligned and robotic.
make it yours
Remix it
- Cat choireasy
Add three small open mouths and make the music note pulse like a sound wave.
- Costume partyeasy
Give each kitten a tiny hat or bow by adding one shape above its head.
- Dance squadmedium
Add two more kittens in the back row, smaller and darker, dancing on a half-beat delay.
- Spotlightmedium
Darken the background to a soft stage and add a yellow cone behind the trio.
challenge extension
Turn the dance into a kickline: lift each kitten's front paw higher on alternating beats, and add tiny dust puffs under their feet on every landing.
keep sketching
More tutorials to try
Pick another small recipe and borrow one technique for your next doodle.