Skip to content
CoDdleCoDoodle home
Animal DoodlesBeginnerHTML + CSS

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

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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>
Open in Playground

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

Pick another small recipe and borrow one technique for your next doodle.