67
A cheeky little number 67 that just can't stop bouncing.
← you, in 15 minutes.
what you'll build
Here's the plan
A chunky number 67 whose two digits hop on opposite beats — the 6 springs up as the 7 dips down, then they swap — a playful nod to the viral 6-7 hand seesaw. The digits are drawn as stacked strokes (a wide navy 'ink' stroke plus a narrower colour stroke) so they read as bold outlined numbers without any web font, then a squash-and-stretch hop with a half-cycle offset makes them alternate.
You’ll learn
- Drawing chunky outlined numbers as two stacked strokes (wide navy under, narrower colour on top)
- Tucking a simple face into the six's loop so a plain number reads as a character
- Faking weight with squash-and-stretch — squashed on the ground, stretched at the top of the hop
- Offsetting one animation by half its duration (a negative animation-delay) so two things alternate
- Skill level
- Beginner
- Time
- ~15 min
- Tools
- Just a browser
- Code type
- SVG + CSS
- Lines
- ~42
the steps
Build it, one change at a time
Set the stage
Warm paper, a soft shadow under each digit's landing spot, a couple of sparkles, and two little whoosh lines. The shadows stay outside the hopping groups so they stay on the ground.
<rect x="0" y="0" width="200" height="200" rx="18" fill="#FBF2E5" stroke="none"/> <!-- one shadow under each digit --> <ellipse class="ss-shadow-6" cx="75" cy="181" rx="30" ry="8" fill="#2B3A55" opacity="0.18" stroke="none"/> <ellipse class="ss-shadow-7" cx="130" cy="181" rx="27" ry="8" fill="#2B3A55" opacity="0.18" stroke="none"/> <g stroke="#2B3A55" stroke-width="3" stroke-linecap="round" opacity="0.4" fill="none"> <path d="M34 150 q-6 6 -2 14"/> <path d="M166 150 q6 6 2 14"/> </g> <path class="ss-spark ss-spark1" d="M32 52 L35 60 L32 68 L29 60 Z" fill="#FF6B5E" stroke="none"/> <path class="ss-spark ss-spark2" d="M170 60 L173 66 L170 72 L167 66 Z" fill="#2B3A55" stroke="none"/>an empty stage: a shadow under each spot, two sparkles, and a hint of bounce.
Draw the chunky 67
Draw the 6 and the 7 as TWO separate groups (so each can hop on its own beat later). Each digit is one path drawn twice: a wide navy stroke for the ink outline, then a narrower colour stroke on top — coral for the 6, sunshine for the 7. Round caps and joins keep it soft and hand-drawn.
<g class="ss-six"> <!-- the "6": navy outline + coral fill --> <path d="M86 74 C62 78 48 104 48 130 C48 152 63 164 82 162 C100 160 108 145 103 130 C98 117 82 113 71 124" fill="none" stroke="#2B3A55" stroke-width="21" stroke-linecap="round" stroke-linejoin="round"/> <path d="M86 74 C62 78 48 104 48 130 C48 152 63 164 82 162 C100 160 108 145 103 130 C98 117 82 113 71 124" fill="none" stroke="#FF6B5E" stroke-width="13" stroke-linecap="round" stroke-linejoin="round"/> </g> <g class="ss-seven"> <!-- the "7": navy outline + sunshine fill --> <path d="M112 82 L158 82 L130 164" fill="none" stroke="#2B3A55" stroke-width="21" stroke-linecap="round" stroke-linejoin="round"/> <path d="M112 82 L158 82 L130 164" fill="none" stroke="#FFD84D" stroke-width="13" stroke-linecap="round" stroke-linejoin="round"/> </g>a bold, chunky 67 — coral six, sunshine seven, ready to bounce.
Give it a face
Tuck a tiny happy face into the six's loop — two dot eyes with white highlights, a small smile, and soft coral blush. Add it inside the six's group so it rides along when the 6 hops. That's all it takes to turn a number into a little character.
<g class="ss-face"> <ellipse class="ss-eye" cx="76" cy="139" rx="2.9" ry="3.9" fill="#2B3A55"/> <ellipse class="ss-eye" cx="91" cy="139" rx="2.9" ry="3.9" fill="#2B3A55"/> <circle cx="74.8" cy="137.6" r="1" fill="#FFFDF7"/> <circle cx="89.8" cy="137.6" r="1" fill="#FFFDF7"/> <path d="M78 147 C82 152 87 152 90 147" fill="none" stroke="#2B3A55" stroke-width="2.6" stroke-linecap="round"/> <circle cx="70" cy="146" r="2.8" fill="#FF8FA3" opacity="0.7"/> <circle cx="96" cy="146" r="2.8" fill="#FF8FA3" opacity="0.7"/> </g>the finished static 67, grinning in its little loop.
Make them hop alternately
Give each digit the SAME springy squash-and-stretch hop, anchored at its own feet — but start the seven half a cycle late with a negative animation-delay (-0.6s of the 1.2s loop). Now the 6 is up while the 7 is down, then they swap: the viral 6-7 seesaw. Each shadow shrinks as its digit rises (with the matching offset). It all lives inside @media (prefers-reduced-motion: no-preference) so it freezes when motion isn't wanted.
@media (prefers-reduced-motion: no-preference) { /* same hop on both digits — the seven just starts half a cycle later */ .ss .ss-six { transform-origin: 76px 166px; animation: ss-hop 1.2s ease-in-out infinite; } .ss .ss-seven { transform-origin: 130px 166px; animation: ss-hop 1.2s ease-in-out -0.6s infinite; } .ss .ss-shadow-6 { transform-box: fill-box; transform-origin: center; animation: ss-sh 1.2s ease-in-out infinite; } .ss .ss-shadow-7 { transform-box: fill-box; transform-origin: center; animation: ss-sh 1.2s ease-in-out -0.6s infinite; } .ss .ss-eye { transform-box: fill-box; transform-origin: center; animation: ss-blink 4.6s ease-in-out infinite; } .ss .ss-spark { transform-box: fill-box; transform-origin: center; } .ss .ss-spark1 { animation: ss-tw 2.4s ease-in-out infinite; } .ss .ss-spark2 { animation: ss-tw 2.4s ease-in-out 0.9s infinite; } } @keyframes ss-hop { 0%, 100% { transform: translateY(0) scale(1.05, 0.9); } 50% { transform: translateY(-24px) scale(0.97, 1.08); } } @keyframes ss-sh { 0%, 100% { transform: scaleX(1); opacity: 0.18; } 50% { transform: scaleX(0.6); opacity: 0.1; } } @keyframes ss-blink { 0%, 42%, 48%, 92%, 100% { transform: scaleY(1); } 45%, 95% { transform: scaleY(0.1); } } @keyframes ss-tw { 0%, 100% { opacity: 0.35; transform: scale(0.8); } 45% { opacity: 1; transform: scale(1.15); } }the 6 and 7 seesawing up and down on opposite beats — pure 6-7 energy.
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="ss" viewBox="0 0 200 200" width="200" height="200" role="img" aria-label="A number 67 doodle whose digits hop up and down alternately">
<rect x="0" y="0" width="200" height="200" rx="18" fill="#FBF2E5" stroke="none"/>
<ellipse class="ss-shadow-6" cx="75" cy="181" rx="30" ry="8" fill="#2B3A55" opacity="0.18" stroke="none"/>
<ellipse class="ss-shadow-7" cx="130" cy="181" rx="27" ry="8" fill="#2B3A55" opacity="0.18" stroke="none"/>
<g stroke="#2B3A55" stroke-width="3" stroke-linecap="round" opacity="0.4" fill="none">
<path d="M34 150 q-6 6 -2 14"/>
<path d="M166 150 q6 6 2 14"/>
</g>
<path class="ss-spark ss-spark1" d="M32 52 L35 60 L32 68 L29 60 Z" fill="#FF6B5E" stroke="none"/>
<path class="ss-spark ss-spark2" d="M170 60 L173 66 L170 72 L167 66 Z" fill="#2B3A55" stroke="none"/>
<g class="ss-six">
<path d="M86 74 C62 78 48 104 48 130 C48 152 63 164 82 162 C100 160 108 145 103 130 C98 117 82 113 71 124" fill="none" stroke="#2B3A55" stroke-width="21" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M86 74 C62 78 48 104 48 130 C48 152 63 164 82 162 C100 160 108 145 103 130 C98 117 82 113 71 124" fill="none" stroke="#FF6B5E" stroke-width="13" stroke-linecap="round" stroke-linejoin="round"/>
<g class="ss-face">
<ellipse class="ss-eye" cx="76" cy="139" rx="2.9" ry="3.9" fill="#2B3A55" stroke="none"/>
<ellipse class="ss-eye" cx="91" cy="139" rx="2.9" ry="3.9" fill="#2B3A55" stroke="none"/>
<circle cx="74.8" cy="137.6" r="1" fill="#FFFDF7" stroke="none"/>
<circle cx="89.8" cy="137.6" r="1" fill="#FFFDF7" stroke="none"/>
<path d="M78 147 C82 152 87 152 90 147" fill="none" stroke="#2B3A55" stroke-width="2.6" stroke-linecap="round"/>
<circle cx="70" cy="146" r="2.8" fill="#FF8FA3" stroke="none" opacity="0.7"/>
<circle cx="96" cy="146" r="2.8" fill="#FF8FA3" stroke="none" opacity="0.7"/>
</g>
</g>
<g class="ss-seven">
<path d="M112 82 L158 82 L130 164" fill="none" stroke="#2B3A55" stroke-width="21" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M112 82 L158 82 L130 164" fill="none" stroke="#FFD84D" stroke-width="13" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>
tips & gotchas
Mistakes we actually made
The outlined-number trick is just one path drawn twice — a wide navy stroke, then a narrower colour stroke on top. Round caps sell the handmade look.
The alternation is pure timing: both digits share one hop animation, but the seven gets animation-delay: -0.6s (half the 1.2s loop) so it's always on the opposite beat.
Anchor each hop's transform-origin at that digit's own feet, and shrink its shadow at the apex so the bounce reads as real height.
make it yours
Remix it
- New colourseasy
Recolour the two fill strokes — try mint + sky, or make both digits the same colour.
- Faster / floatiereasy
Shorten the loop to ~1s for a hyper seesaw, or lengthen it for a slow, floaty one.
- Different numbereasy
Swap the two digit paths for your own lucky number using the same stroke trick.
- Spin at the topmedium
Add a tiny rotate() at the 50% (apex) of ss-hop for a cheeky flip at the peak of each hop.
challenge extension
Same alternating-hop trick, new subject: make two letters or shapes seesaw up and down on opposite beats using one shared animation and a half-cycle delay.