Blinking Cat
A round cat whose blink is three lines of keyframes.
← you, in 30 minutes.
what you'll build
Here's the plan
A round, blinking cat drawn with a handful of divs and the same border-radius trick from the onigiri — now curled into a cozy night window scene with a cushion, moon, and stars. Still just HTML and CSS.
You’ll learn
- Layering a simple scene behind a character with source order and positioned divs
- Reusing one border-radius shape across ears, head, and nose by just changing the numbers
- Mirroring a shape with transform: scaleX(-1) instead of hand-tuning a second version
- Building a "w" mouth from two overlapping arcs — a trick that shows up in every doodle face
- Animating just one property (scaleY) to fake a blink without redrawing anything
- Skill level
- Beginner
- Time
- ~30 min
- Tools
- Just a browser
- Code type
- HTML + CSS
- Lines
- ~154
the steps
Build it, one change at a time
Set the stage
Start with a tiny night scene: a soft blue window, a crescent moon, two twinkly stars, and a round coral cushion. The cat still starts as one soft head shape, but now it has somewhere cozy to sit.
<div class="scene"> <div class="window"> <div class="moon"></div> <div class="star star-one"></div> <div class="star star-two"></div> <div class="window-bar window-bar-v"></div> <div class="window-bar window-bar-h"></div> </div> <div class="cushion"></div> <div class="cat"> <div class="ear ear-left"></div> <div class="ear ear-right"></div> <div class="head"> <div class="eye eye-left"></div> <div class="eye eye-right"></div> <div class="nose"></div> <div class="mouth mouth-left"></div> <div class="mouth mouth-right"></div> </div> </div> </div> .scene { position: relative; width: 200px; height: 200px; } .window { position: absolute; top: 6px; left: 28px; width: 132px; height: 84px; background: #BFD9F2; border: 6px solid #2B3A55; border-radius: 14px; overflow: hidden; } .moon { position: absolute; top: 16px; left: 22px; width: 28px; height: 28px; background: #FFD84D; border-radius: 50%; } .moon::after { content: ""; position: absolute; top: -3px; left: 9px; width: 28px; height: 28px; background: #BFD9F2; border-radius: 50%; } .star { position: absolute; width: 7px; height: 7px; background: #FFD84D; border-radius: 50%; animation: star-twinkle 2.8s ease-in-out infinite; } .star-one { top: 18px; right: 30px; } .star-two { top: 48px; right: 54px; animation-delay: 1.1s; } .window-bar { position: absolute; background: #2B3A55; } .window-bar-v { top: 0; bottom: 0; left: 50%; width: 6px; margin-left: -3px; } .window-bar-h { left: 0; right: 0; top: 50%; height: 6px; margin-top: -3px; } .cushion { position: absolute; left: 24px; bottom: 6px; width: 140px; height: 46px; background: #FF6B5E; border: 6px solid #2B3A55; border-radius: 50%; } .scene > .cat { position: absolute; bottom: 16px; left: 50%; /* shrink the cat so the window and cushion get to be part of the story */ transform: translateX(-50%) scale(0.74); transform-origin: 50% 100%; } .cat { position: relative; width: 190px; height: 180px; } .head { position: absolute; inset: 24px 0 0 0; background: #FFFDF7; border: 6px solid #2B3A55; border-radius: 48% 48% 50% 50% / 55% 55% 45% 45%; } @keyframes star-twinkle { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } } @media (prefers-reduced-motion: reduce) { .star { animation: none; } }a sleepy night window, a round cushion, and one soft cat head settling in.
Add pointy ears
A triangle-ish ear is just a square with one soft corner (border-radius: 12% 75% 8% 55%). Draw it once for the left ear, then flip it for the right one with scaleX(-1) instead of redrawing the whole shape.
.ear { position: absolute; top: 4px; width: 52px; height: 52px; background: #FFFDF7; border: 6px solid #2B3A55; /* a triangle-ish ear is just a square with one soft corner */ border-radius: 12% 75% 8% 55%; } .ear-left { left: 16px; transform: rotate(-8deg); } .ear-right { right: 16px; transform: rotate(8deg) scaleX(-1); }ears! Now it's unmistakably a cat with a very good window seat.
Give it eyes and a nose
Two dot eyes and a small rounded nose, positioned by percentage against the head — the same absolute-centering approach from the onigiri, just with two more dots.
.eye { position: absolute; top: 44%; width: 16px; height: 16px; background: #2B3A55; border-radius: 50%; } .eye-left { left: 24%; } .eye-right { right: 24%; } .nose { position: absolute; top: 56%; left: 50%; transform: translateX(-50%); width: 13px; height: 9px; background: #FFB3AD; border-radius: 50% 50% 60% 60%; }eyes and a little nose. It's staring right at you from the cushion.
Draw the "w" mouth
A cat mouth is two mismatched arcs, not one shape. Each is a bottom-only rounded border (border-top: none) so only the curve shows — overlap two of them and you get a convincing little "w".
/* the "w" mouth: two little arcs */ .mouth { position: absolute; top: 62%; width: 16px; height: 9px; border: 3.5px solid #2B3A55; border-top: none; border-radius: 0 0 16px 16px; } .mouth-left { left: 41%; } .mouth-right { right: 41%; }a little cat smile — two mismatched arcs doing the work of one mouth.
Make it blink
A blink is just scaleY squashing the eye flat for one keyframe out of a long, mostly-still cycle — no eyelid element, no extra markup, just motion.
.eye { /* ...existing eye rules... */ animation: cat-blink 3.6s ease-in-out infinite; } @keyframes cat-blink { 0%, 88%, 100% { transform: scaleY(1); } 93% { transform: scaleY(0.08); } }the finished, occasionally-blinking cat in its cozy night scene.
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.
<div class="scene">
<div class="window">
<div class="moon"></div>
<div class="star star-one"></div>
<div class="star star-two"></div>
<div class="window-bar window-bar-v"></div>
<div class="window-bar window-bar-h"></div>
</div>
<div class="cushion"></div>
<div class="cat">
<div class="ear ear-left"></div>
<div class="ear ear-right"></div>
<div class="head">
<div class="eye eye-left"></div>
<div class="eye eye-right"></div>
<div class="nose"></div>
<div class="mouth mouth-left"></div>
<div class="mouth mouth-right"></div>
</div>
</div>
</div>
tips & gotchas
Mistakes we actually made
If the mirrored ear looks stretched instead of flipped, check that scaleX(-1) comes after the rotate — order matters in a transform list.
top: 44% for the eyes is measured against .head, not .cat — percentages always resolve against the nearest positioned parent.
A blink is just scaleY(0.08) for one keyframe — no eyelid element required.
make it yours
Remix it
- New coateasy
Swap the background and border colors on .head for a tabby, black cat, or something stranger.
- Sleepy eyeseasy
Slow the cat-blink duration to 6s for a much calmer cat.
- Winkmedium
Give .eye-left its own keyframe so only one eye blinks.
- Whiskersmedium
Three thin absolutely-positioned lines per cheek, angled outward.
challenge extension
Same shapes, new animal: draw its floppy-eared dog friend using the same head + ear + face recipe, just with longer, softer ears.
keep sketching
More tutorials to try
Pick another small recipe and borrow one technique for your next doodle.