Skip to content
CoDdleCoDoodle home
Fan Art PracticeBeginnerSVG + CSS

Pikachu

An electric friend built from layered SVG shapes — zigzag tail included.

This coded drawing is a fan-art practice example created for educational purposes only. Pokémon, Pikachu, and related characters are trademarks and copyrighted properties of Nintendo, Game Freak, and Creatures Inc. CoDoodle is not affiliated with, endorsed by, or sponsored by Nintendo, Game Freak, or Creatures Inc.

← you, in 35 minutes.

what you'll build

Here's the plan

A sunshine-yellow chibi Pikachu resting in a soft meadow — first the sky-and-grass scene, then the character (chibi body, ink-tipped ears, and a zigzag lightning tail), then its face and markings, and finally one tiny idle ear-twitch. Educational fan art: the same scene-then-character layering works for any original character.

You’ll learn

  • Building a scene back-to-front — a flat sky and ground wash first, then the character on top
  • Layering simple SVG shapes (ellipses, one jagged path) the way you'd layer divs in CSS art
  • Drawing a lightning-bolt tail as a single multi-point path, tucked under the body so it reads as attached
  • Animating one small part (an ear) on its own transform-origin without touching anything else
Skill level
Beginner
Time
~35 min
Tools
Just a browser
Code type
SVG + CSS
Lines
~47

the steps

Build it, one change at a time

  1. Set the meadow scene

    Before the character, lay down the world: a pale sky rectangle up top, a mint ground rectangle below, a soft shadow where the character will sit, a few ink grass blades, a doodle cloud, and a little spark. Flat background shapes first means everything you draw next sits neatly on top.

    <!-- sky wash, full-bleed top -->
    <rect x="0" y="0" width="230" height="140" fill="#E6EFFF" stroke="none"/>
    <!-- mint meadow ground, full-bleed bottom -->
    <rect x="0" y="140" width="230" height="70" fill="#5ECBB4" stroke="none"/>
    <!-- soft ground shadow anchoring the character -->
    <ellipse cx="115" cy="190" rx="60" ry="11" fill="#2B3A55" stroke="none" opacity="0.18"/>
    <!-- grass tufts (thin ink blades) -->
    <path d="M28 200 Q31 188 34 200" fill="none" stroke="#2B3A55" stroke-width="3" stroke-linecap="round" opacity="0.55"/>
    <path d="M42 202 Q45 192 48 202" fill="none" stroke="#2B3A55" stroke-width="3" stroke-linecap="round" opacity="0.5"/>
    <path d="M188 200 Q191 188 194 200" fill="none" stroke="#2B3A55" stroke-width="3" stroke-linecap="round" opacity="0.55"/>
    <!-- a soft doodle cloud top-left -->
    <g class="cloud" fill="#FFFDF7" stroke="#2B3A55" stroke-width="6.5" stroke-linecap="round" stroke-linejoin="round">
      <rect x="18" y="34" width="54" height="14" rx="7"/>
      <circle cx="28" cy="30" r="11"/>
      <circle cx="46" cy="24" r="13"/>
      <circle cx="64" cy="32" r="10"/>
    </g>
    <!-- a tiny electric spark accent top-right -->
    <path class="spark" d="M198 52 L202 44 L206 52 L214 56 L206 60 L202 68 L198 60 L190 56 Z" fill="#FFD84D" stroke="#2B3A55" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
    

    an empty little meadow — sky, grass, a cloud and a spark, waiting for its star.

  2. Block in the character

    The whole silhouette in one pass, drawn tail-first so its base tucks under the body: the zigzag lightning tail, two ink-tipped ears (a base tilt on the outer group, the inner one left free to animate later), a squat body, little arms and feet, and a big head on top. Chibi proportions do most of the "cute" work already.

    <g class="character" fill="#FFD84D" stroke="#2B3A55" stroke-width="6.5" stroke-linecap="round" stroke-linejoin="round">
      <!-- zigzag lightning tail — base tucks under the body -->
      <path class="tail" d="M138 156 L156 152 L180 114 L168 110 L190 78 L178 74 L198 44 L220 38 L210 76 L222 80 L200 116 L210 120 L178 160 Z"/>
      <!-- ears: base rotation on the outer group, animation on the inner -->
      <g transform="rotate(-22 62 30)">
        <g class="ear ear-left">
          <ellipse cx="62" cy="30" rx="14" ry="36"/>
          <ellipse cx="50" cy="2" rx="10" ry="14" fill="#2B3A55" stroke="none"/>
        </g>
      </g>
      <g transform="rotate(24 168 30)">
        <g class="ear ear-right">
          <ellipse cx="168" cy="30" rx="14" ry="36"/>
          <ellipse cx="180" cy="2" rx="10" ry="14" fill="#2B3A55" stroke="none"/>
        </g>
      </g>
      <ellipse class="body" cx="115" cy="150" rx="40" ry="36"/>
      <ellipse cx="74" cy="140" rx="9" ry="16" transform="rotate(28 74 140)"/>
      <ellipse cx="156" cy="140" rx="9" ry="16" transform="rotate(-28 156 140)"/>
      <ellipse cx="92" cy="184" rx="15" ry="9"/>
      <ellipse cx="138" cy="184" rx="15" ry="9"/>
      <ellipse class="head" cx="115" cy="76" rx="68" ry="56"/>
    </g>
    

    a plain yellow character standing in the meadow — body, ears, tail, no face yet.

  3. Add the face and markings

    Two brown back-stripe arcs, then the face: ink eyes with tiny highlight dots, round coral cheeks, a small nose, and a curved mouth. These go after the body in the markup, so they layer on top of it — paint order is doing the work.

    <!-- back stripes -->
    <path d="M84 156 Q115 165 146 156" fill="none" stroke="#C98A5B" stroke-width="9"/>
    <path d="M90 170 Q115 178 140 170" fill="none" stroke="#C98A5B" stroke-width="9"/>
    <!-- face: eyes + highlight dots, cheeks, nose, mouth -->
    <circle cx="85" cy="72" r="7" fill="#2B3A55" stroke="none"/>
    <circle cx="145" cy="72" r="7" fill="#2B3A55" stroke="none"/>
    <circle cx="87.5" cy="69.5" r="2.2" fill="#FFFDF7" stroke="none"/>
    <circle cx="147.5" cy="69.5" r="2.2" fill="#FFFDF7" stroke="none"/>
    <circle cx="60" cy="100" r="13" fill="#FF6B5E" stroke="none"/>
    <circle cx="170" cy="100" r="13" fill="#FF6B5E" stroke="none"/>
    <ellipse cx="115" cy="84" rx="3.5" ry="2.5" fill="#2B3A55" stroke="none"/>
    <path d="M100 96 Q108 104 115 96 Q122 104 130 96" fill="none" stroke-width="4"/>
    

    eyes, cheeks and back stripes — now it's unmistakably a cheerful electric mouse.

  4. Twitch an ear

    One keyframe on the right ear's own transform-origin makes it flick every few seconds — a small idle motion that brings the whole doodle to life without touching any other shape. transform-origin uses the SVG's own coordinate space (168px 30px), not CSS pixels.

    /* one tiny idle motion: the right ear twitches every few seconds */
    .pikachu .ear-right {
      transform-origin: 168px 30px;
      animation: ear-twitch 3.8s ease-in-out infinite;
    }
    @keyframes ear-twitch {
      0%, 84%, 100% { transform: rotate(0deg); }
      89% { transform: rotate(9deg); }
      94% { transform: rotate(-4deg); }
    }
    

    the finished Pikachu in its meadow, one ear twitching every few seconds.

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="pikachu" viewBox="0 0 230 210" width="230" height="210" role="img" aria-label="Pikachu fan-art doodle">
  <!-- sky wash, full-bleed top -->
  <rect x="0" y="0" width="230" height="140" fill="#E6EFFF" stroke="none"/>
  <!-- mint meadow ground, full-bleed bottom -->
  <rect x="0" y="140" width="230" height="70" fill="#5ECBB4" stroke="none"/>
  <!-- soft ground shadow anchoring the character -->
  <ellipse cx="115" cy="190" rx="60" ry="11" fill="#2B3A55" stroke="none" opacity="0.18"/>
  <!-- grass tufts (thin ink blades) -->
  <path d="M28 200 Q31 188 34 200" fill="none" stroke="#2B3A55" stroke-width="3" stroke-linecap="round" opacity="0.55"/>
  <path d="M42 202 Q45 192 48 202" fill="none" stroke="#2B3A55" stroke-width="3" stroke-linecap="round" opacity="0.5"/>
  <path d="M188 200 Q191 188 194 200" fill="none" stroke="#2B3A55" stroke-width="3" stroke-linecap="round" opacity="0.55"/>
  <!-- a soft doodle cloud top-left -->
  <g class="cloud" fill="#FFFDF7" stroke="#2B3A55" stroke-width="6.5" stroke-linecap="round" stroke-linejoin="round">
    <rect x="18" y="34" width="54" height="14" rx="7"/>
    <circle cx="28" cy="30" r="11"/>
    <circle cx="46" cy="24" r="13"/>
    <circle cx="64" cy="32" r="10"/>
  </g>
  <!-- a tiny electric spark accent top-right -->
  <path class="spark" d="M198 52 L202 44 L206 52 L214 56 L206 60 L202 68 L198 60 L190 56 Z" fill="#FFD84D" stroke="#2B3A55" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
  <g class="character" fill="#FFD84D" stroke="#2B3A55" stroke-width="6.5" stroke-linecap="round" stroke-linejoin="round">
    <!-- zigzag lightning tail -->
    <path class="tail" d="M138 156 L156 152 L180 114 L168 110 L190 78 L178 74 L198 44 L220 38 L210 76 L222 80 L200 116 L210 120 L178 160 Z"/>
    <!-- ears: long, tipped in ink -->
    <g transform="rotate(-22 62 30)">
      <g class="ear ear-left">
        <ellipse cx="62" cy="30" rx="14" ry="36"/>
        <ellipse cx="50" cy="2" rx="10" ry="14" fill="#2B3A55" stroke="none"/>
      </g>
    </g>
    <g transform="rotate(24 168 30)">
      <g class="ear ear-right">
        <ellipse cx="168" cy="30" rx="14" ry="36"/>
        <ellipse cx="180" cy="2" rx="10" ry="14" fill="#2B3A55" stroke="none"/>
      </g>
    </g>
    <!-- body -->
    <ellipse class="body" cx="115" cy="150" rx="40" ry="36"/>
    <!-- back stripes -->
    <path d="M84 156 Q115 165 146 156" fill="none" stroke="#C98A5B" stroke-width="9"/>
    <path d="M90 170 Q115 178 140 170" fill="none" stroke="#C98A5B" stroke-width="9"/>
    <!-- arms -->
    <ellipse cx="74" cy="140" rx="9" ry="16" transform="rotate(28 74 140)"/>
    <ellipse cx="156" cy="140" rx="9" ry="16" transform="rotate(-28 156 140)"/>
    <!-- feet -->
    <ellipse cx="92" cy="184" rx="15" ry="9"/>
    <ellipse cx="138" cy="184" rx="15" ry="9"/>
    <!-- head -->
    <ellipse class="head" cx="115" cy="76" rx="68" ry="56"/>
    <!-- face -->
    <circle cx="85" cy="72" r="7" fill="#2B3A55" stroke="none"/>
    <circle cx="145" cy="72" r="7" fill="#2B3A55" stroke="none"/>
    <circle cx="87.5" cy="69.5" r="2.2" fill="#FFFDF7" stroke="none"/>
    <circle cx="147.5" cy="69.5" r="2.2" fill="#FFFDF7" stroke="none"/>
    <circle cx="60" cy="100" r="13" fill="#FF6B5E" stroke="none"/>
    <circle cx="170" cy="100" r="13" fill="#FF6B5E" stroke="none"/>
    <ellipse cx="115" cy="84" rx="3.5" ry="2.5" fill="#2B3A55" stroke="none"/>
    <path d="M100 96 Q108 104 115 96 Q122 104 130 96" fill="none" stroke-width="4"/>
  </g>
</svg>
Open in Playground

tips & gotchas

Mistakes we actually made

Paint order follows document order: the flat scenery is drawn first so the character sits on top, and within the character the tail comes before the body so its base tucks under.

transform-origin on an SVG element needs coordinates in the SVG's own coordinate space, not CSS pixels — that's why ear-twitch uses 168px 30px, matching the viewBox.

The ear's resting tilt lives on an outer <g> and the twitch animates an inner <g>, so the idle motion adds to the base angle instead of fighting it.

make it yours

Remix it

  • Recoloreasy

    Swap the #FFD84D fill for any color; the ink outline (#2B3A55) does the rest of the work.

  • Bigger cheekseasy

    Bump the cheek circles' r value for a rosier fan-art style.

  • Both ears twitchmedium

    Copy ear-twitch onto .ear-left with an offset animation-delay so they don't move in sync.

  • Golden hourmedium

    Warm the sky rect toward peach and deepen the ground color for a sunset meadow.

challenge extension

Same scene-then-character layering, new fan-art subject: set a tiny world first, then build its star on top — you'll reuse almost every trick from this page.

keep sketching

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