GODRICH

손그림 디자인 랜딩 UI 키트, 크레용 섹션 9개

손그림 디자인은 굵고 삐뚤빼뚤한 크레용 선으로 테두리를 그리고, 그 선만 SVG 필터로 살짝 흔들어 종이 위에 손으로 그은 낙서처럼 보이게 만드는 스타일입니다. 동네 미술학원이나 어린이 브랜드 사이트에서 본 그 느낌인데 이름을 몰라 검색을 못 했던 바로 그 화면입니다.

핀터레스트에 캡처로만 저장해 두던 이 화면을, 실제로 만든 원페이지로 아래에 그대로 올렸습니다. 내비게이션부터 푸터까지 스크롤하면서 전체 인상을 먼저 확인해 보세요.

새 창에서 원페이지 열기

이번엔 그 화면을 뜯어서 낱개 부품 아홉 종으로 다시 배열했습니다. 처음 랜딩을 열었을 때 시선이 흐르는 순서 — 둘러보기, 기능 확인, 가격, 신뢰, 행동 유도, 가입 — 를 그대로 따릅니다. 손으로 그린 줄 알았는데 사실 CSS였던 부분은 셋(낙서 히어로·이중선 카드·지그재그 푸터)이 전부 같은 원리로 돌아간다는 것입니다. 테두리나 윗변을 그리는 도형에만 흔들림 필터 또는 들쭉날쭉한 절단선을 걸고, 글자를 담은 요소는 건드리지 않습니다.

자동 재생 · 눌러서 해당 항목으로 · 전부 한 zip

이 키트의 색은 일곱 개로 끝납니다. 글자는 항상 잉크색 하나로 고정하는 것이 읽히는 손그림의 조건입니다.

역할 쓰는 곳
종이 #fff8ef 페이지 바탕 전체
잉크 #33261c 모든 글자 (대비 12.1~13.9:1)
레드 크레용 #ff5a5f 손그림 선·강조 테두리
옐로 크레용 #ffcd3c 버튼·별·밑줄
블루 크레용 #4fa3e3 이중선·포커스 링
그린 크레용 #6dbe6d 체크·아바타
퍼플 크레용 #a685e2 CTA 배경 틴트

01크레용 낙서 히어로

카드 테두리는 글자와 분리된 SVG 사각형 레이어이고, 그 레이어에만 feTurbulence 흔들림 필터를 걸어 굵은 점선이 손으로 그은 것처럼 삐뚤거립니다. 제목 아래 노란 밑줄은 stroke-dashoffset으로 그려졌다 지워지길 반복합니다.

stroke-dashoffset 밑줄손그림 border-radiusradius 24
<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>

02손그림 동그라미 내비

활성 탭 글자 둘레를 빨간 크레용 동그라미가 감싸는데, 완벽한 원이 아니라 한쪽 끝이 다른 쪽을 살짝 지나치는 이중 루프라 방금 그린 것처럼 보입니다. stroke-dasharray를 다 그렸다가 반대 방향으로 지웁니다.

stroke-dashoffset 재생겹쳐 그린 원radius pill
<li class="relative px-2 py-1">
  <span class="relative z-10 text-xs font-semibold">홈</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>

03삐뚤빼뚤 스티커 카드 격자

카드마다 빨강·파랑 두 선을 1~2px 어긋나게 겹쳐 크레용으로 두 번 그은 흔적을 냅니다. 카드 네 장은 시작 시각을 140ms씩 어긋내 순서대로 살짝 기웁니다.

비대칭 border-radius이중선 오프셋2열→1열
<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>

04손그림 체크 목록

체크 표시는 아이콘 폰트가 아니라 획 하나짜리 SVG 경로가 왼쪽부터 오른쪽까지 그려지는 애니메이션입니다. 행마다 색과 시작 시각이 달라 체크가 제 박자로 완성됩니다.

stroke-dashoffset 체크어긋난 시작 시각radius 12
<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>

05별표 동그라미 요금제

세 요금제 카드는 저마다 다른 크레용 톤이고, 추천 플랜의 가격 숫자만 손그림 동그라미가 스스로 둘러 그려지며 옆에 작은 별 두 개가 다른 박자로 반짝입니다. 표 없이 색과 동그라미만으로 눈이 갑니다.

stroke-dashoffset 원반짝이는 별radius 24
.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; }
}

06크레용 말풍선 후기

말풍선은 반듯한 사각형이 아니라 윤곽선이 울퉁불퉁한 SVG 패스이고, 꼬리도 매끈한 삼각형 대신 꺾인 선 두 개로 그립니다. 별점은 다섯 개 폭을 100·100·100·80·40%로 다르게 채워 진짜 후기처럼 보이게 했습니다.

울퉁불퉁 테두리부분 채움 별점radius 16
<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>

07크레용 해칭 CTA 밴드

밴드 배경은 이미지 없이 repeating-linear-gradient 한 줄로 그린 빗금 해칭이고, 그 위 버튼은 빨간 점선 테두리가 계속 행진하듯 다시 그려집니다. 색칠북 한 페이지에 놓인 버튼 같습니다.

repeating-linear-gradient 해칭이중선 재생radius pill
.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; } }

08가위질 지그재그 푸터

푸터 윗변은 조각마다 요소를 하나씩 두지 않고 clip-path: polygon() 하나로 높낮이가 들쭉날쭉한 톱니를 그려 아이가 가위로 대충 오린 것처럼 보이게 합니다. 균일한 지그재그가 아니라 점마다 높이가 다른 게 핵심입니다.

clip-path 지그재그3열→1열반짝임 점
.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%
  );
}

09이중선 크레용 버튼·인풋

버튼은 빨강·파랑 두 선이 살짝 어긋났다 돌아오길 반복해 손맛을 내고, 입력창은 손으로 두른 파란 동그라미가 계속 번지듯 커졌다 사라지길 반복합니다. 키보드로 초점을 옮기면 버튼과 입력창 둘 다 별도의 :focus-visible 윤곽선이 뜹니다.

이중선 어긋남focus 손그림 원radius 12
.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); }
}

tailwind.config 커스텀

크레용 일곱 색과 반경 세 종을 이 한 곳에 적어 두면 원페이지와 부품 아홉 개가 전부 같은 규칙을 따라갑니다. 흔들림 필터의 id는 부품마다 rough1·rough2처럼 번호를 따로 붙여 겹치지 않게 하고, 전체를 모은 원페이지에서만 rough 하나로 합칩니다.

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" },
  },
},

바이브코딩 프롬프트

config를 프로젝트에 넣은 뒤 Claude Code·Cursor에 건네는 말은 SVG 필터를 어디에 걸고 어디에 걸지 않는지가 핵심입니다. 지시문 전문은 zip의 prompt.md에 담겨 있습니다.

배경은 paper(#fff8ef) 하나로 통일한다. 테두리가 있는 박스마다 흔들리는 손그림
테두리(SVG feTurbulence + feDisplacementMap)를 별도 레이어로 건다 — 글자를
감싸는 요소 전체에는 절대 걸지 않는다. 카드 모서리는 rounded-crayon 또는
rounded-pill로 통일한다. 이중선을 쓸 땐 빨강과 파랑을 1~2px 어긋나게 겹친다.

이 지시문을 page/index.html로 실제로 구현해 1280px 화면 전체를 찍은 것이 아래 그림입니다.

결과

어디서 깨지는가 — 함정

가장 먼저 겪은 함정은 흔들림 필터를 어디에 거느냐입니다. 처음엔 카드 전체(테두리 더하기 글자)를 통째로 filter: url(#rough)로 감쌌더니 feDisplacementMap이 픽셀을 전부 같은 규칙으로 밀어내는 바람에 제목 글자까지 삐뚤빼뚤 번져 읽기 어려워졌습니다. 테두리를 그리는 SVG rect·path만 별도 레이어로 떼어 놓고 그 레이어에만 필터를 걸자 글자는 또렷하게 남고 테두리만 흔들렸습니다.

두 번째는 실측으로 잡은 숫자입니다. 푸터의 별 두 개 반짝임만으로 움직임을 재니 누적면적이 0.07%로 설정 하한(0.08%)에 못 미쳐 정지 화면과 구분이 안 됐습니다. 별 크기를 14px에서 20px로, 확대 범위를 0.7~1.2배에서 0.5~1.7배로 넓히자 0.35%로 올라가 통과했습니다. 세 번째는 활성 탭을 두르는 동그라미의 크기였습니다. 뷰박스를 92×50으로 처음 그렸더니 렌더된 화면에서 원이 옆 탭 글자까지 침범했고, 56×30으로 줄이고 나서야 "홈" 글자만 정확히 감쌌습니다. 이 세 가지를 다 잡은 완성본을, 이 비밀번호 r6qyfm69이 걸린 zip을 받아 그대로 열어 확인할 수 있습니다.

아홉 개 데모 전부 MDN prefers-reduced-motion 문서가 정의한 미디어 쿼리를 감지하면 선이 그려지는 애니메이션과 카드가 기우는 움직임을 멈추고, 각 요소를 다 그려진 상태(체크는 완성된 모양, 동그라미는 닫힌 원)로 고정합니다.

접근성

손그림 스타일의 가장 흔한 실패는 흔들림 필터를 글자에까지 거는 것입니다. feDisplacementMap은 소스 그래픽의 모든 픽셀을 노이즈 맵 값만큼 밀어내는데, 이건 글자 획도 예외가 아니라서 작은 크기에서는 자모가 뭉개져 읽기 어려워집니다. 이 키트는 그래서 필터를 항상 테두리 전용 SVG 레이어에만 걸고 글자 요소는 건드리지 않습니다. 글자색은 전부 짙은 잉크(#33261c)로 고정해 종이 바탕 위에서 13.9:1, 카드에 쓰는 가장 어두운 틴트(퍼플 틴트) 위에서도 12.1:1로 WCAG 2.1 최소 대비 기준 4.5:1을 넉넉히 넘습니다. 빨강·파랑 강조선은 장식용 테두리라 텍스트 대비 기준 대상이 아니지만, 버튼·입력창의 키보드 초점은 색선에 기대지 않고 :focus-visible 아웃라인을 잉크색으로 별도 그렸습니다.

크레용 말고 다른 밝은 톤 홈페이지 유행이 궁금하면 파스텔 캔디 랜딩도 함께 보시고, 디자인 트렌드 카테고리 전체와 이 블로그 소개는 소개 페이지에 정리해 뒀습니다.

FAQ

손그림 디자인이랑 그냥 스케치 폰트 쓰는 건 뭐가 달라요?

스케치 폰트는 글자 모양 자체를 손글씨처럼 바꾸는 것이고, 이 키트는 글자는 반듯한 서체 그대로 두고 테두리·밑줄·체크 같은 장식 선만 SVG 필터로 흔듭니다. 글자를 흔들면 가독성이 떨어지지만 테두리만 흔들면 귀여움은 살고 읽기는 그대로입니다.

어두운 톤 브랜드에도 이 스타일을 쓸 수 있나요?

쓸 수 있지만 paper(#fff8ef) 대신 짙은 바탕을 쓰려면 잉크 글자색도 밝은색으로 뒤집어야 대비가 유지됩니다. 크레용 선 색 일곱 개 중 빨강·노랑처럼 채도가 높은 색은 어두운 바탕에서도 그대로 써도 되지만, 카드 틴트는 어두운 버전으로 다시 잡아야 합니다.

feTurbulence 필터가 느리진 않나요?

이 키트의 필터는 테두리를 그리는 작은 SVG 레이어 하나에만 걸리고 값이 고정돼 있어(애니메이션 자체는 stroke-dashoffset·transform이 담당) 매 프레임 다시 계산하지 않습니다. 카드 전체나 페이지 전체에 필터를 걸면 느려지니, 항상 테두리 레이어처럼 작은 요소에만 국한해서 씁니다.

압축 비밀번호를 입력하세요

비밀번호는 이 글 본문 안에 있습니다. 읽다 보면 나옵니다.