Crayon Web Design: 9 Hand-Drawn Landing Sections
Crayon web design draws thick, wobbly outlines around cards and buttons and runs an SVG filter on just those outlines, so they read as scribbled by hand rather
That's the crayon-box feel you can't fake with a font — the friendly kids'-studio or handmade-shop look you screenshot on Pinterest and then can't find the name for. Below is a full one-page landing built with it, live, not a mockup. Scroll it top to bottom once before we break it into parts.
Now the same page taken apart into nine reusable pieces, laid out in the order a visitor's eye actually moves through a landing — orient, browse features, check price, trust, act, sign up. Three of them (the scribble hero, the double-line cards, the speech-bubble testimonial) share one trick: the wobble filter sits on a separate SVG layer that draws only the border, never the one wrapping the text.
Auto-plays · click a tile to jump to its section · all nine in one zip
- 01 Crayon-scribble hero
- 02 Hand-drawn circle nav
- 03 Wobbly sticker card grid
- 04 Hand-drawn checklist
- 05 Star-and-circle pricing
- 06 Crayon speech-bubble testimonial
- 07 Crayon-hatch CTA band
- 08 Scissor-cut zigzag footer
- 09 Double-line crayon buttons & inputs
The whole kit runs on seven colors. Text always stays on the one ink color at the bottom of this table — that's what keeps a hand-drawn look legible.
| Role | Color | Used for |
|---|---|---|
| Paper | #fff8ef |
Page background |
| Ink | #33261c |
All text (contrast 12.1–13.9:1) |
| Crayon red | #ff5a5f |
Hand-drawn strokes, accent borders |
| Crayon yellow | #ffcd3c |
Buttons, stars, underline |
| Crayon blue | #4fa3e3 |
Double lines, blooming ring accent |
| Crayon green | #6dbe6d |
Checkmarks, avatars |
| Crayon purple | #a685e2 |
CTA background tint |
01Crayon-scribble hero
The card's border is a separate SVG rect layer, and only that layer carries a feTurbulence wobble filter, so the dashed outline reads as hand-drawn while the headline stays crisp. The yellow underline below the title draws itself on and off with stroke-dashoffset.
<svg width="0" height="0" style="position:absolute">
<filter id="rough" x="-30%" y="-30%" width="160%" height="160%">
<feTurbulence type="fractalNoise" baseFrequency="0.045" numOctaves="2" seed="4" result="n"/>
<feDisplacementMap in="SourceGraphic" in2="n" scale="7"
xChannelSelector="R" yChannelSelector="G"/>
</filter>
</svg>
<svg class="frame" viewBox="0 0 300 190" preserveAspectRatio="none">
<rect x="6" y="6" width="288" height="178" rx="20"
stroke="#33261c" stroke-width="5" stroke-dasharray="16 11"
fill="none" filter="url(#rough)" />
</svg>
02Hand-drawn circle nav
A red crayon loop circles the active tab's label — not a clean ring but a double loop where one end overshoots the other, the way a real hand circles something twice. stroke-dasharray draws it on, holds, then draws it off in reverse.
<li class="relative px-2 py-1">
<span class="relative z-10 text-xs font-semibold">Home</span>
<svg class="loop" viewBox="0 0 56 30">
<path fill="none" stroke="#ff5a5f" stroke-width="3.5"
stroke-linecap="round" stroke-linejoin="round"
stroke-dasharray="110"
d="M28 4 C 13 2, 4 11, 7 17 C 9 25, 20 28, 29 26
C 41 24, 50 17, 47 10 C 45 4, 33 2, 25 5" />
</svg>
</li>
03Wobbly sticker card grid
Each card layers a red and a blue outline offset by 1–2px, the look of a crayon line drawn twice. The four cards tilt in sequence with each one's animation delayed 140ms after the last.
<svg class="frame" viewBox="0 0 100 78" preserveAspectRatio="none">
<rect x="5" y="5" width="90" height="68" rx="12"
fill="none" stroke="#ff5a5f" stroke-width="2.4" />
<rect x="3" y="3" width="90" height="68" rx="12"
fill="none" stroke="#4fa3e3" stroke-width="2.4" opacity=".8" />
</svg>
04Hand-drawn checklist
Each checkmark is one SVG stroke drawing left to right, not an icon font glyph. Every row gets its own color and start delay, so the checks land on their own beat instead of all at once.
<svg class="check" viewBox="0 0 20 16">
<path fill="none" stroke="#ff5a5f" stroke-width="3"
stroke-linecap="round" stroke-linejoin="round"
stroke-dasharray="26"
d="M2 9 C 3 8, 4 10, 7 13 C 10 10, 14 6, 18 2" />
</svg>
<style>
.check path { animation: checkDraw 2s ease-out infinite; }
@keyframes checkDraw {
0% { stroke-dashoffset: 26; opacity: 0; }
45% { stroke-dashoffset: 0; opacity: 1; }
100% { stroke-dashoffset: -26; opacity: 0; }
}
</style>
05Star-and-circle pricing
Three plan cards each sit in a different crayon tone, and only the recommended plan's price gets a hand-drawn circle that loops itself while two small stars twinkle out of sync beside it. No table needed — color and the circle alone say which plan to pick.
.ring-path {
fill: none;
stroke: #ff5a5f;
stroke-width: 3.2;
stroke-dasharray: 190;
animation: ringDraw 2s ease-out infinite;
}
@keyframes ringDraw {
0% { stroke-dashoffset: 190; }
50% { stroke-dashoffset: 0; }
100% { stroke-dashoffset: -190; }
}
06Crayon speech-bubble testimonial
The quote sits inside an SVG path with a bumpy outline instead of a clean rectangle, and the tail is two crooked line segments instead of a neat triangle. The star rating fills five widths at 100/100/100/80/40% so it reads like a real, slightly-mixed review score.
<svg class="frame" viewBox="0 0 260 110" preserveAspectRatio="none">
<path fill="#fff8ef" stroke="#33261c" stroke-width="3" stroke-linejoin="round"
d="M18 10 L242 10 C250 10 252 18 252 26 L252 78 C252 88 248 96 238 96
L48 96 L30 110 L34 94 L18 92 C10 90 8 82 8 74
L8 26 C8 16 10 10 18 10 Z" />
</svg>
07Crayon-hatch CTA band
The band's background is one repeating-linear-gradient line — no image — drawn as tight crayon hatching, and the button on top wears a dashed red frame that keeps marching, as if it's being redrawn in a loop. It reads like a button sitting on a page from a coloring book.
.band {
background:
repeating-linear-gradient(45deg, rgba(51,38,28,.08) 0 2px, transparent 2px 9px),
#efe6fb;
}
.btn-rect {
fill: none; stroke: #ff5a5f; stroke-width: 3;
stroke-dasharray: 14 8;
animation: march 2s linear infinite;
}
@keyframes march { to { stroke-dashoffset: -440; } }
08Scissor-cut zigzag footer
The footer's top edge is one clip-path: polygon() with teeth of uneven height — not one element per notch — so it reads like a kid's rough scissor cut instead of a machine-perfect zigzag. Uneven height at each point is what sells the illusion.
.zigzag {
height: 14px;
background: #33261c;
clip-path: polygon(
0% 100%, 0% 30%, 6% 85%, 12% 15%, 18% 90%, 24% 20%,
30% 88%, 36% 12%, 42% 92%, 48% 18%, 54% 85%, 60% 22%,
66% 90%, 72% 15%, 78% 88%, 84% 20%, 90% 92%, 96% 14%,
100% 30%, 100% 100%
);
}
09Double-line crayon buttons & inputs
The button carries a red-and-blue double outline that drifts slightly out of register on a loop, and the input grows a loosely hand-drawn blue circle that blooms outward and fades on its own repeating cycle.
.btn-rect-a { stroke: #ff5a5f; animation: shiftA 2s infinite; }
.btn-rect-b { stroke: #4fa3e3; opacity: .85; animation: shiftB 2s infinite; }
@keyframes shiftA { 50% { transform: translate(-2px, 1px); } }
@keyframes shiftB { 50% { transform: translate(2px, -1px); } }
.ring-rect { animation: bloom 2s infinite; }
@keyframes bloom {
0%, 100% { opacity: 0; transform: scale(.9); }
50% { opacity: 1; transform: scale(1); }
}
Custom tailwind.config
Keep the seven crayon colors and three radii in this one place and both the one-pager and all nine parts stay in sync. The wobble filter's id should also stay singular across a project — reuse it, don't redeclare it.
theme: {
extend: {
colors: {
paper: "#fff8ef", ink: "#33261c", red: "#ff5a5f",
yellow: "#ffcd3c", blue: "#4fa3e3", green: "#6dbe6d", purple: "#a685e2",
},
borderRadius: { crayon: "20px", control: "12px", pill: "999px" },
spacing: { gutter: "16px" },
},
},
Vibe-Coding Prompt
Once the config is in your project, the instruction to Claude Code or Cursor comes down to where you do and don't attach the wobble filter. The full prompt text lives in the zip's prompt.md.
Keep the background a single paper color (#fff8ef). Every bordered box gets a
wobbly hand-drawn outline (SVG feTurbulence + feDisplacementMap) on its own
layer — never on the element wrapping the text itself. Round corners to
rounded-crayon or rounded-pill only. For double lines, offset a red and a
blue stroke by 1-2px.
Here's what that prompt produced when applied to page/index.html, captured as a full 1280px screenshot.

Where it breaks (the trap)
The first real trap was where the wobble filter gets attached. Wrapping the whole card — border and headline together — in filter: url(#rough) pushed every pixel through the same displacement map, so the title text warped along with the border and got hard to read at small sizes. Pulling the border into its own SVG rect/path layer and filtering only that layer fixed it — the text stayed sharp, only the outline wobbled.
The second trap showed up in the actual motion measurement. With just two 14px stars blinking in the footer, the measured changed-pixel area came out to 0.07%, under this site's 0.08% floor — visually indistinguishable from a static frame. Growing the stars to 20px and widening the scale range from 0.7–1.2x to 0.5–1.7x pushed it to 0.35%, which passed. The third trap was the size of the circle around the active nav tab: a 92×50 viewBox let the loop spill into the next tab's label, and shrinking it to 56×30 made it hug only the intended word. All three fixes are in the zip behind the password r6qyfm69.
All nine demos detect MDN's prefers-reduced-motion media query and stop the line-draw and card-tilt animations, freezing every element in its finished state — a completed checkmark, a closed circle — instead of hiding it.
Accessibility
The most common way a hand-drawn kit fails accessibility is running the wobble filter on the text itself. feDisplacementMap pushes every pixel of the source graphic by the noise map's value, letter strokes included, and at small sizes that blurs glyphs into illegibility. This kit keeps the filter on a border-only SVG layer at all times and never touches text elements. Text stays on one dark ink (#33261c), reaching 13.9:1 against the paper background and 12.1:1 against the darkest tint in the kit (the purple card tint) — well past the WCAG 2.1 minimum contrast of 4.5:1. The red and blue accent strokes are decorative borders and aren't held to text contrast rules, but keyboard focus on every button and input is drawn with its own :focus-visible outline, not left to depend on a colored line.
If pastel is more your brand's speed than crayon, the pastel candy landing kit covers that ground, and the full design trends category and this site's about page round out where else to look.
FAQ
How is crayon web design different from just using a sketch font?
A sketch font reshapes the letters themselves to look handwritten; this kit keeps letters in a clean typeface and only wobbles the decorative lines — borders, underlines, checkmarks — with an SVG filter. Wobbling text hurts readability; wobbling only the border keeps the charm without losing it.
Can this style work for a dark-themed brand?
Yes, but swapping paper (#fff8ef) for a dark background means flipping the ink text color to something light too, or contrast collapses. The saturated crayon reds and yellows still read fine on dark backgrounds; the card tints need a darker version of themselves to stay in balance.
Is the feTurbulence filter slow to render?
It's applied to one small SVG layer per border and its values are fixed, so it isn't recomputed every frame — the motion you see comes from stroke-dashoffset and transform, not from re-running the filter. Filtering a whole card or the full page would be the slow version; keep it scoped to small border layers like this kit does.