Bubble Tea Buddy
A friendly bubble tea cup with boba pearls, a straw, and a sweet blinking face.
← you, in 25 minutes.
what you'll build
Here's the plan
A friendly bubble tea cup character with a domed lid, tall coral straw, boba pearls inside, rosy cheeks, and little arms hugging the cup — all animated with subtle keyframes.
You’ll learn
- Build a character from a cup body, domed lid, and straw
- Layer shapes so pearls sit inside the cup and the straw pokes through the lid
- Group face parts for an independent blink animation
- Stagger multiple small animations (bob, wiggle, blink) so nothing syncs up
- Skill level
- Beginner
- Time
- ~25 min
- Tools
- Just a browser
- Code type
- SVG + CSS
- Lines
- ~55
the steps
Build it, one change at a time
Cup body and domed lid
Draw a cream-colored cup with rounded shoulders and a domed lid on top. A small straw hole in the lid tells the viewer where the straw will go later.
<!-- cup body: milk-tea cream with rounded shoulders --> <path class="cup-body" d="M 72 84 C 72 170, 82 188, 90 190 L 140 190 C 148 188, 158 170, 158 84 Z" fill="#F7EDE2" stroke="#2B3A55" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/> <!-- domed lid --> <g class="lid" fill="#FFF8F0" stroke="#2B3A55" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"> <rect x="70" y="78" width="90" height="16" rx="4"/> <ellipse cx="115" cy="72" rx="50" ry="22"/> <ellipse cx="128" cy="70" rx="7" ry="4" fill="none" stroke-width="3"/> </g>a simple cup and lid — a blank canvas for straw, pearls, and a face.
Straw, boba pearls, and face
Thread a tall coral straw through the lid hole, drop five boba pearls near the bottom, and add a tiny friendly face. The pearls sit in front of the cup body but behind the lid, so order matters.
<!-- tall coral straw --> <g class="straw" stroke-linecap="round"> <line x1="130" y1="12" x2="128" y2="108" stroke="#FF7F6B" stroke-width="12"/> <line x1="126" y1="12" x2="124" y2="108" stroke="#FF9E8E" stroke-width="3" opacity="0.7"/> </g> <!-- boba pearls --> <g class="pearls" fill="#4A3B2A" stroke="#2B3A55" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"> <circle class="pearl" cx="95" cy="176" r="8"/> <circle class="pearl" cx="115" cy="182" r="8"/> <circle class="pearl" cx="135" cy="174" r="8"/> <circle class="pearl" cx="105" cy="164" r="7"/> <circle class="pearl" cx="125" cy="166" r="7"/> </g> <!-- tiny friendly face --> <g class="face"> <g class="eye eye-left"><circle cx="95" cy="112" r="5" fill="#2B3A55"/></g> <g class="eye eye-right"><circle cx="135" cy="112" r="5" fill="#2B3A55"/></g> <path d="M 108 124 Q 115 129 122 124" fill="none" stroke="#2B3A55" stroke-width="3" stroke-linecap="round"/> </g>straw, pearls, and a sweet little face — it's already a character.
Cheeks and hugging arms
Add two soft coral blush circles and a pair of small arms wrapping around the cup. The arms make the cup feel like it's holding itself in excitement.
<!-- rosy cheeks --> <g class="cheeks"> <circle cx="82" cy="120" r="7" fill="#FF9E8E" opacity="0.65"/> <circle cx="148" cy="120" r="7" fill="#FF9E8E" opacity="0.65"/> </g> <!-- arms/hands hugging the cup --> <g class="arms" fill="#FF7F6B" stroke="#2B3A55" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"> <path d="M 78 140 Q 58 155 88 168" fill="none" stroke-width="7"/> <path d="M 152 140 Q 172 155 142 168" fill="none" stroke-width="7"/> <circle class="hand" cx="88" cy="168" r="6"/> <circle class="hand" cx="142" cy="168" r="6"/> </g>rosy cheeks and hugging arms — the bubble tea buddy is complete, minus motion.
Boba bob, straw wiggle, and blink
Give each pearl its own bob with staggered animation-delay, wiggle the straw around its base, and blink the eyes once every few seconds. Wrap everything in prefers-reduced-motion so the cup stays still when needed.
.bubble-tea-buddy .pearl { transform-origin: center; } .bubble-tea-buddy .eye-left { transform-origin: 95px 112px; } .bubble-tea-buddy .eye-right { transform-origin: 135px 112px; } .bubble-tea-buddy .straw { transform-origin: 128px 108px; } @media (prefers-reduced-motion: no-preference) { .bubble-tea-buddy .pearl { animation: pearl-bob 2.2s ease-in-out infinite; } .bubble-tea-buddy .pearl:nth-child(2) { animation-delay: 0.35s; } .bubble-tea-buddy .pearl:nth-child(3) { animation-delay: 0.7s; } .bubble-tea-buddy .pearl:nth-child(4) { animation-delay: 1.05s; } .bubble-tea-buddy .pearl:nth-child(5) { animation-delay: 1.4s; } .bubble-tea-buddy .straw { animation: straw-wiggle 3s ease-in-out infinite; } .bubble-tea-buddy .eye { animation: eye-blink 4s ease-in-out infinite; } } @keyframes pearl-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-5px); } } @keyframes straw-wiggle { 0%, 100% { transform: rotate(0deg); } 25% { transform: rotate(1.2deg); } 75% { transform: rotate(-0.8deg); } } @keyframes eye-blink { 0%, 90%, 100% { transform: scaleY(1); } 95% { transform: scaleY(0.1); } }the finished bubble tea buddy — boba pearls bob, straw wiggles, eyes blink.
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="bubble-tea-buddy" viewBox="0 0 230 210" width="230" height="210" role="img" aria-label="Bubble Tea Buddy cute drink character"> <!-- cup body: milk-tea cream with rounded shoulders -->
<path class="cup-body" d="M 72 84 C 72 170, 82 188, 90 190 L 140 190 C 148 188, 158 170, 158 84 Z" fill="#F7EDE2" stroke="#2B3A55" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
<!-- domed lid -->
<g class="lid" fill="#FFF8F0" stroke="#2B3A55" stroke-width="6" stroke-linecap="round" stroke-linejoin="round">
<rect x="70" y="78" width="90" height="16" rx="4"/>
<ellipse cx="115" cy="72" rx="50" ry="22"/>
<!-- small straw hole rim -->
<ellipse cx="128" cy="70" rx="7" ry="4" fill="none" stroke-width="3"/>
</g>
<!-- tall coral straw poking through the lid -->
<g class="straw" stroke-linecap="round">
<line x1="130" y1="12" x2="128" y2="108" stroke="#FF7F6B" stroke-width="12"/>
<line x1="126" y1="12" x2="124" y2="108" stroke="#FF9E8E" stroke-width="3" opacity="0.7"/>
</g>
<!-- boba pearls inside the cup -->
<g class="pearls" fill="#4A3B2A" stroke="#2B3A55" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
<circle class="pearl" cx="95" cy="176" r="8"/>
<circle class="pearl" cx="115" cy="182" r="8"/>
<circle class="pearl" cx="135" cy="174" r="8"/>
<circle class="pearl" cx="105" cy="164" r="7"/>
<circle class="pearl" cx="125" cy="166" r="7"/>
</g>
<!-- tiny friendly face -->
<g class="face">
<g class="eye eye-left">
<circle cx="95" cy="112" r="5" fill="#2B3A55"/>
</g>
<g class="eye eye-right">
<circle cx="135" cy="112" r="5" fill="#2B3A55"/>
</g>
<path d="M 108 124 Q 115 129 122 124" fill="none" stroke="#2B3A55" stroke-width="3" stroke-linecap="round"/>
</g>
<!-- rosy cheeks -->
<g class="cheeks">
<circle cx="82" cy="120" r="7" fill="#FF9E8E" opacity="0.65"/>
<circle cx="148" cy="120" r="7" fill="#FF9E8E" opacity="0.65"/>
</g>
<!-- arms/hands hugging the cup -->
<g class="arms" fill="#FF7F6B" stroke="#2B3A55" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
<path d="M 78 140 Q 58 155 88 168" fill="none" stroke-width="7"/>
<path d="M 152 140 Q 172 155 142 168" fill="none" stroke-width="7"/>
<circle class="hand" cx="88" cy="168" r="6"/>
<circle class="hand" cx="142" cy="168" r="6"/>
</g>
</svg>
tips & gotchas
Mistakes we actually made
Draw the cup body first, then the pearls, then the lid and straw last, so the straw pokes out and the lid covers the cup rim.
A staggered bob is just the same keyframe with different animation-delay values — no need to write five separate animations.
Set transform-origin on the straw near its base (128px 108px) so the wiggle looks like a gentle sway, not a spin.
The blink holds the eyes open 90% of the loop — that's what makes it feel natural instead of frantic.
Use thick rounded strokes (stroke-linecap='round') everywhere for a soft sticker look.
make it yours
Remix it
- New drink coloreasy
Swap the cream cup fill for matcha green, taro purple, or coffee brown.
- Different straweasy
Change the straw color or angle it a little more to the right.
- More pearlsmedium
Add two or three smaller pearls near the top of the cup.
- Winking facemedium
Give each eye its own keyframe so they blink at different times.
challenge extension
Same cup technique, new drink: build an iced coffee cup with a green straw, three ice cubes, and a slow condensation drip.