You will build a friendly cartoon cat using only HTML and CSS. By the end, you will have a tidy component with ears, eyes, whiskers, paws, and a swishy tail. The process teaches shape composition, layering with pseudo-elements, and small animations that feel alive.
Why CSS Art: How to Draw a Cartoon Cat Matters
CSS art trains you to think in primitives: triangles, circles, rectangles, gradients, and borders. That skill transfers to icons, mascots, onboarding illustrations, and loading screens without shipping any image assets. You keep control over theming through CSS variables, avoid extra network requests, and gain pixel-level precision. A cat is a compact project that touches many classic tricks: border triangles, rounded shapes, shadows for depth, and transform-based motion.
Prerequisites
You do not need JavaScript or a graphics tool. Some CSS fundamentals make the steps smoother.
- Basic HTML
- CSS custom properties
- CSS pseudo-elements (::before / ::after)
Step 1: The HTML Structure
The markup is a single wrapper with semantic blocks for head, ears, face, body, paws, and tail. Each part stays generic and class-based, so you can theme the cat later or swap sizes without rewriting HTML. Pseudo-elements will handle small details like whiskers and mouth curves to keep the markup lean.
/* HTML */
Step 2: The Basic CSS & Styling
Start with variables for colors and a predictable layout. The stage centers the cat and provides a soft backdrop. The .cat element is a positioned container that all parts anchor to. The sizes below target a medium component you can scale later with a single transform.
/* CSS */
* { box-sizing: border-box; }
:root {
--fur: #f2a36f;
--fur-dark: #c97c47;
--inner-ear: #f6c0b1;
--eye: #ffffff;
--pupil: #2b2b2b;
--nose: #cc5b6a;
--whisker: #6b6b6b;
--belly: #f7ddcd;
--line: #2b2020;
--bg1: #f0f4ff;
--bg2: #e6ecff;
}
body {
min-height: 100vh;
margin: 0;
display: grid;
place-items: center;
background: linear-gradient(180deg, var(--bg1), var(--bg2));
font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
}
.stage {
width: 420px;
height: 420px;
display: grid;
place-items: center;
}
.cat {
position: relative;
width: 280px;
height: 320px;
transform: translateZ(0); /* create its own layer for smoother transforms */
}
Advanced Tip: Theme this cat by overriding the variables in a wrapper class. For example, a “black cat” palette or a high-contrast version for dark UIs is a one-liner when you define all colors as custom properties.
Step 3: Building the Head and Ears
The head is a circle with a soft shadow. Ears use border triangles. A second triangle inside each ear adds depth and reads as inner ear skin.
/* CSS */
.head {
position: absolute;
top: 20px;
left: 50%;
width: 180px;
height: 180px;
transform: translateX(-50%);
background: var(--fur);
border-radius: 50%;
box-shadow:
inset 0 -8px 0 rgba(0,0,0,0.06),
0 8px 16px rgba(0,0,0,0.08);
}
.ear {
position: absolute;
width: 0;
height: 0;
border-left: 36px solid transparent;
border-right: 36px solid transparent;
border-bottom: 60px solid var(--fur);
top: -10px;
}
.ear--left { left: 16px; transform: rotate(-6deg); }
.ear--right { right: 16px; transform: rotate(6deg); }
.inner-ear {
position: absolute;
width: 0;
height: 0;
border-left: 24px solid transparent;
border-right: 24px solid transparent;
border-bottom: 42px solid var(--inner-ear);
top: 2px;
opacity: 0.95;
}
.inner-ear--left { left: 28px; transform: rotate(-6deg); }
.inner-ear--right { right: 28px; transform: rotate(6deg); }
.face {
position: absolute;
inset: 0;
}
How This Works (Code Breakdown)
The head sets a positioning context for ears and facial features. A circle comes from equal width and height with border-radius: 50%. If you want a primer on that trick, see how to make a circle with CSS. The inset shadow grounds the face and gives volume without a heavy outline.
Each ear uses the border triangle technique. A triangle forms when two side borders are transparent and one border has color and height. The ear elements use border-bottom for the visible flap. The slight rotation gives a relaxed stance. If you have never built this shape, the step-by-step on how to make a triangle up with CSS covers the border math well.
Inner ears mirror the same triangle method at a smaller size with a different color, offset forward to sit neatly inside the outer ear. Using two layers reads well at any scale and avoids extra markup.
Step 4: Building the Face and Body
Eyes, pupils, muzzle, nose, mouth, and whiskers bring the personality. The body is a rounded capsule with a lighter belly, simple paws, and a striped tail.
/* CSS */
.eye {
position: absolute;
top: 68px;
width: 32px;
height: 42px;
background: var(--eye);
border-radius: 50%;
box-shadow: 0 2px 0 rgba(0,0,0,0.06);
overflow: hidden;
}
.eye--left { left: 50px; }
.eye--right { right: 50px; }
.pupil {
position: absolute;
top: 12px;
left: 9px;
width: 14px;
height: 20px;
background: var(--pupil);
border-radius: 50%;
transition: transform 180ms ease;
}
.muzzle {
position: absolute;
left: 50%;
bottom: 26px;
width: 120px;
height: 74px;
transform: translateX(-50%);
background: var(--belly);
border-radius: 55% 55% 70% 70% / 60% 60% 80% 80%;
box-shadow: inset 0 -4px 0 rgba(0,0,0,0.06);
}
.nose {
position: absolute;
top: 12px;
left: 50%;
transform: translateX(-50%);
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 12px solid var(--nose);
}
.mouth {
position: absolute;
top: 28px;
left: 50%;
width: 34px;
height: 18px;
transform: translateX(-50%);
}
.mouth::before,
.mouth::after {
content: "";
position: absolute;
width: 20px;
height: 16px;
border-bottom: 3px solid var(--line);
border-left: 3px solid var(--line);
border-radius: 0 0 16px 16px;
top: 0;
}
.mouth::before {
right: 50%;
transform: rotate(-18deg);
transform-origin: right top;
}
.mouth::after {
left: 50%;
transform: scaleX(-1) rotate(-18deg);
transform-origin: left top;
}
.whiskers {
position: absolute;
top: 36px;
width: 44px;
height: 2px;
background: var(--whisker);
}
.whiskers--left {
right: 100%;
margin-right: 10px;
transform: rotate(-8deg);
box-shadow:
0 -8px 0 0 var(--whisker),
0 8px 0 0 var(--whisker);
}
.whiskers--right {
left: 100%;
margin-left: 10px;
transform: rotate(8deg);
box-shadow:
0 -8px 0 0 var(--whisker),
0 8px 0 0 var(--whisker);
}
.body {
position: absolute;
top: 160px;
left: 50%;
transform: translateX(-50%);
width: 220px;
height: 160px;
background: var(--fur);
border-radius: 110px 110px 90px 90px;
box-shadow: 0 10px 18px rgba(0,0,0,0.08);
}
.belly {
position: absolute;
left: 50%;
top: 28px;
width: 130px;
height: 100px;
transform: translateX(-50%);
background: var(--belly);
border-radius: 60% 60% 70% 70%;
box-shadow: inset 0 -6px 0 rgba(0,0,0,0.05);
}
.paw {
position: absolute;
bottom: -2px;
width: 58px;
height: 30px;
background: var(--fur);
border-radius: 0 0 16px 16px;
box-shadow: 0 2px 0 rgba(0,0,0,0.06);
}
.paw--left { left: 32px; }
.paw--right { right: 32px; }
.paw::after {
content: "";
position: absolute;
left: 10px;
right: 10px;
bottom: 6px;
height: 2px;
background:
linear-gradient(90deg,
transparent 0 8px,
rgba(0,0,0,0.12) 8px 10px,
transparent 10px 18px,
rgba(0,0,0,0.12) 18px 20px,
transparent 20px 28px,
rgba(0,0,0,0.12) 28px 30px,
transparent 30px 100%);
}
.tail {
position: absolute;
right: -4px;
top: 44px;
width: 24px;
height: 140px;
background:
repeating-linear-gradient(
90deg,
var(--fur-dark) 0 12px,
var(--fur) 12px 24px
);
border-radius: 14px;
transform-origin: top center;
transform: rotate(18deg);
box-shadow: 0 8px 14px rgba(0,0,0,0.08);
}
How This Works (Code Breakdown)
Eyes are simple circles with overflow hidden. Pupils sit inside as smaller circles and use a transition so they can nudge on hover later. For more on the base shape, this guide on how to make a circle with CSS shows variations for sizing and centering.
The muzzle is an oval with a softer bottom-half radius. The mixed border-radius syntax lets you set horizontal and vertical radii separately to get that rounded snout. If you want a pure oval base for a different style, this explainer on how to make an oval with CSS walks through the typical patterns.
The nose uses a small border triangle flipped downward by using border-top for the colored edge. The mouth curves come from two pseudo-elements that draw only the bottom and left borders, rounded into a subtle arc, then mirrored with a scaleX(-1). This avoids extra DOM nodes and lets the cat smile without custom SVG paths.
Whiskers are three parallel strokes created from one base line and two shadows above and below it. A small rotation on each side pushes them outward. The body is a capsule with a high radius, and the lighter belly adds contrast and reads as fluff. Paws are rounded rectangles with a faint set of toe lines added by a gradient. The tail is a rounded rectangle rotated at the base and filled with a repeating linear gradient to form stripes. All parts sit inside one positioned container, which keeps stacking under control.
Advanced Techniques: Adding Animations & Hover Effects
A few subtle motions bring the cat to life. Eye blinks, a swinging tail, and a slight ear twitch on hover feel playful without stealing attention. Keep animations on transform or opacity for smoothness.
/* CSS */
@keyframes blink {
0%, 4%, 100% { transform: scaleY(1); }
2% { transform: scaleY(0.1); }
}
@keyframes tail-sway {
0%, 100% { transform: rotate(18deg); }
50% { transform: rotate(10deg); }
}
.eye::after {
content: "";
position: absolute;
inset: 0;
background: var(--fur);
transform-origin: top center;
transform: scaleY(0);
animation: blink 5.5s infinite;
opacity: 0.98;
}
.eye--right::after { animation-delay: 0.2s; }
.tail { animation: tail-sway 3.4s ease-in-out infinite; }
.cat:hover .pupil {
transform: translate(2px, 2px);
}
.ear--left, .ear--right {
transition: transform 180ms ease;
}
.cat:hover .ear--left { transform: rotate(-12deg); }
.cat:hover .ear--right { transform: rotate(12deg); }
/* Respect reduced motion preferences */
@media (prefers-reduced-motion: reduce) {
* { animation: none !important; transition: none !important; }
}
The eyelid effect uses an overlay that scales vertically from the top. A very short closed state sells a blink without distracting. The tail runs a slow rotate around its base, which reads as a gentle sway. Pupils slide a few pixels toward the pointer on hover to suggest focus, and ears tilt a bit for personality. The reduced motion query switches animations off for sensitive users.
Accessibility & Performance
CSS art is decoration by default, but it can carry meaning in some contexts. Treat it as you would any iconography: announce it only when it adds information, and keep motion friendly.
Accessibility
If your cat is decorative, leave aria-hidden=”true” on the wrapper so screen readers skip it. If it conveys meaning, switch to role=”img” and provide a short aria-label like “Cat mascot”. For motion, respect prefers-reduced-motion to avoid unexpected animation for users who turn it off at the OS level. Keep color contrast in mind if you plan to place text near the cat or integrate it into buttons.
Performance
The layout relies on a handful of elements and sticks to transforms for motion. That choice keeps rendering cheap on modern engines. Avoid animating box-shadow or filter on big layers, and avoid very large drop shadows. If you scale the entire cat, prefer a container transform over recalculating every dimension. Sprite-like stripes use a lightweight repeating-linear-gradient, so they cost less than multiple DOM nodes.
From Simple Shapes to a Playful Cat
You assembled a complete cartoon cat using only CSS: circle head, border-triangle ears, oval muzzle, a capsule body, and small details that add charm. You now have a reusable component that themes well, ships no images, and teaches techniques you can apply to icons, badges, and empty states. Try a new palette, swap ear sizes, or add a collar to grow your own CSS menagerie.