주니어 때 디자인 파일을 받으면 바로 코드를 치기 시작했다. 위에서부터 아래로, 보이는 대로 옮겼다. 그러다 보면 항상 같은 문제가 생겼다. 중간에 컴포넌트 구조를 바꿔야 하거나, 디자이너가 의도한 인터랙션을 놓치거나, 반응형을 나중에 붙이려니 처음부터 다시 짜야 하거나.
지금은 코드를 치기 전에 하는 단계가 더 많아졌다. 그리고 그게 오히려 전체 시간을 줄여준다.
1단계: 디자인 파일 전체를 먼저 훑는다
피그마 파일을 열면 바로 Inspect 패널을 보는 게 아니라, 전체 페이지 흐름을 먼저 파악한다.
- 이 기능에 화면이 몇 개인지
- 화면 간의 이동 흐름이 어떻게 되는지
- 공통으로 쓰이는 요소가 뭔지
- 반응형 디자인이 있는지 (모바일/데스크탑)
- 에러 상태, 빈 상태, 로딩 상태가 디자인에 포함되어 있는지
특히 마지막이 중요하다. 에러/빈/로딩 상태가 디자인에 없으면 개발할 때 임의로 만들게 되고, 나중에 디자이너가 보고 "이건 의도한 게 아닌데요"라고 한다. 빠진 상태가 있으면 코드를 치기 전에 디자이너에게 물어본다.
2단계: 컴포넌트 분리
디자인을 보면서 머릿속으로 컴포넌트를 나눈다. 이때 기준은 크게 세 가지다.
반복되는 요소. 리스트 아이템, 카드, 태그 같은 것들. 한 화면에서 같은 패턴이 2번 이상 나오면 컴포넌트로 뺀다.
독립적인 영역. 헤더, 사이드바, 모달처럼 나머지 UI와 독립적으로 존재하는 영역. 이건 당연히 분리한다.
복잡도. 하나의 컴포넌트가 너무 커지면 (JSX가 100줄 이상이면) 의미 있는 단위로 쪼갠다. 여기서 "의미 있는"이라는 게 애매한데, 나는 "이 부분을 한 문장으로 설명할 수 있는가"를 기준으로 삼는다. "유저 프로필 카드", "결제 수단 선택 섹션", "주문 요약 테이블" 같은 식으로.
예를 들어 이런 상품 상세 페이지가 있다고 하자.
ProductDetailPage
├── ProductImageGallery (상품 이미지 슬라이더)
├── ProductInfo (상품명, 가격, 설명)
│ ├── PriceDisplay (할인가/정가 표시)
│ └── ColorSelector (색상 선택 옵션)
├── ProductTabs (상세정보/리뷰/문의 탭)
│ ├── DetailTab
│ ├── ReviewTab
│ │ └── ReviewItem (개별 리뷰)
│ └── InquiryTab
└── FloatingPurchaseBar (하단 고정 구매 버튼)
이 구조를 코드 치기 전에 먼저 잡아둔다. 노트앱에 적거나, 피그마 코멘트로 남기거나.
3단계: 디자인 스펙 읽기
피그마의 Dev Mode나 Inspect 패널에서 확인할 것들.
spacing과 sizing. 요소 간의 간격, 패딩, 마진. 피그마에서 요소를 선택하고 다른 요소에 마우스를 올리면 간격이 나온다. 이때 4의 배수인지 확인한다. 디자이너가 8px 그리드를 쓰고 있다면 4, 8, 12, 16, 20, 24, 32, 40, 48 같은 값들이 나올 거다. 가끔 13px이나 7px 같은 애매한 값이 나오면, 디자이너의 의도인지 실수인지 확인한다. 대부분 실수다.
typography. 폰트 패밀리, 사이즈, weight, line-height, letter-spacing. 피그마에서 텍스트를 클릭하면 전부 나온다. 이때 디자인 시스템의 typography scale과 맞는지 확인한다. text-sm, text-base, text-lg 같은 이미 정의된 스타일이 있으면 그걸 쓰고, 피그마에 나온 px 값을 하드코딩하지 않는다.
color. 색상이 디자인 토큰으로 정의되어 있는지 확인한다. #2563EB 같은 원시 값이 아니라 primary-500 같은 토큰으로 매핑할 수 있어야 한다. 피그마의 Color Styles를 확인하면 된다.
Auto Layout 속성. 피그마의 Auto Layout은 CSS Flexbox와 거의 1:1 대응된다.
| 피그마 Auto Layout | CSS Flexbox |
|---|---|
| Horizontal | flex-direction: row |
| Vertical | flex-direction: column |
| Gap | gap |
| Padding | padding |
| Fill container | flex: 1 |
| Hug contents | width: fit-content |
이 대응 관계를 알고 있으면 피그마 속성을 바로 CSS로 옮길 수 있다.
4단계: 정적 UI부터 만든다
인터랙션, API 연동, 상태 관리는 전부 뒤로 미루고, 먼저 눈에 보이는 UI만 만든다.
// 1차: 정적 UI
function ProductInfo() {
return (
<div className="flex flex-col gap-4">
<h1 className="text-2xl font-bold">프리미엄 러닝화</h1>
<PriceDisplay original={129000} discounted={89000} />
<p className="text-gray-600 text-sm leading-relaxed">
가볍고 쿠셔닝이 뛰어난 러닝화입니다.
</p>
<ColorSelector
colors={['black', 'white', 'navy']}
selected="black"
onSelect={()=> {}}
/>
</div>
);
}하드코딩된 데이터로 먼저 화면을 만든다. 이 단계에서 디자이너에게 보여주고 1차 피드백을 받는다. API 연동 후에 UI 수정 요청이 오면 양쪽을 다 고쳐야 하니까, UI 확정을 먼저 받는 게 효율적이다.
5단계: 반응형
모바일 디자인이 있다면 모바일 우선(mobile-first)으로 작업한다. 이유는 간단하다. 작은 화면에서 시작해서 넓히는 게, 넓은 화면에서 시작해서 줄이는 것보다 쉽다.
<div className="
grid grid-cols-1 gap-4
md:grid-cols-2 md:gap-6
lg:grid-cols-3 lg:gap-8
">
{products.map(product => (
<ProductCard key={product.id} product={product} />
))}
</div>반응형에서 자주 실수하는 것: 피그마에 모바일(375px)과 데스크탑(1440px)만 있고 태블릿이 없는 경우. 이때 768px~1024px 사이에서 UI가 어정쩡하게 깨지는 경우가 많다. 디자인이 없더라도 이 구간을 직접 확인하면서 조정해야 한다.
디자이너와의 커뮤니케이션
경험에서 배운 몇 가지.
구현이 어려운 게 아니라 비용이 큰 것을 설명한다. "이건 못 해요"보다 "이건 할 수 있는데, 이 방식으로 하면 3일이 더 걸려요. 이렇게 바꾸면 반나절이면 됩니다"가 훨씬 생산적이다. 디자이너도 일정을 안다. 대안을 함께 고민하면 더 좋은 결과가 나올 때가 많다.
"이거 인터랙션이 어떻게 되는 거예요?"를 빨리 물어본다. 정적 화면만 보면 모르는 게 많다. 드롭다운이 열릴 때 나머지 콘텐츠가 밀리는지 오버레이로 뜨는지. 모달이 닫힐 때 애니메이션이 있는지. 에러 메시지가 인풋 아래에 나오는지 토스트로 나오는지. 나중에 물어보면 이미 구조를 잘못 잡은 경우가 있다.
피그마 코멘트를 적극적으로 쓴다. 슬랙 메시지는 묻힌다. 피그마 코멘트는 해당 디자인 옆에 붙어 있으니까 컨텍스트가 유지된다. "이 부분 line-height가 디자인 시스템의 text-sm과 2px 차이가 나는데, 의도인가요?"같은 질문을 코멘트로 남기면 디자이너가 정확한 맥락에서 확인할 수 있다.
코드를 빨리 치는 것보다 코드를 덜 고치는 게 빠르다. 그리고 코드를 덜 고치려면 코드를 치기 전에 더 많이 확인해야 한다. 좀 귀찮아도 이 과정을 습관으로 만들면 전체 개발 시간이 줄어드는 걸 몸으로 느끼게 된다. 최소한 나는 그랬다.
