| name | figma-to-html |
| description | Figma 디자인을 정적 HTML/CSS로 변환합니다. Figma 링크나 node-id가 제공되면 MCP를 통해 디자인 정보를 가져와 정확한 코드를 생성합니다. Use when converting Figma designs to HTML/CSS, or when user mentions Figma links, design conversion, or static HTML implementation. |
Figma to HTML/CSS 변환
Figma 디자인을 정적 HTML/CSS로 변환하는 Skill입니다. 스크립트 작업은 하지 않습니다 (순수 퍼블리싱).
사전 조건
- Figma Desktop 앱 실행 중
- 대상 Figma 파일이 열려 있음
- Figma MCP 서버 등록됨
claude mcp add figma-desktop --transport http --url http://127.0.0.1:3845/mcp
워크플로우
1. Figma 링크에서 node-id 추출
- URL의 node-id 파라미터: 25-1393 → 25:1393 (하이픈을 콜론으로)
2. MCP 도구 호출 (병렬 실행)
├─ get_design_context (dirForAssetWrites 필수!)
│ └─ 에셋 자동 다운로드 + Tailwind 코드 반환
└─ get_screenshot
└─ Figma 원본 스크린샷 (비교 기준)
3. Tailwind → 순수 CSS 변환
- MCP가 제공한 값 그대로 사용 (추측 금지!)
4. HTML/CSS 파일 생성
- 에셋 경로: ./assets/파일명.svg
5. Playwright 스크린샷 캡처
- viewport를 Figma 프레임 크기와 동일하게 설정
6. 시각적 비교
├─ get_screenshot 결과 (원본)
└─ Playwright 스크린샷 (구현물)
7. 차이점 발견 시
├─ MCP 데이터 다시 확인
├─ CSS 수정 (추측 금지, 데이터 기반)
└─ 5-6 반복
8. 완료 판단
└─ 원본과 구현물이 시각적으로 일치할 때만 완료
MCP 도구 사용
디자인 정보 + 에셋 다운로드
mcp__figma-desktop__get_design_context({
nodeId: "781:47496",
clientLanguages: "html,css",
clientFrameworks: "vanilla",
dirForAssetWrites: "./Figma_Conversion/Conversion/[프로젝트명]/[컴포넌트명]/assets"
})
필수: dirForAssetWrites 파라미터로 에셋 자동 저장
원본 스크린샷 (비교 기준)
mcp__figma-desktop__get_screenshot({ nodeId: "781:47496" })
출력 폴더 구조
Figma_Conversion/Conversion/
└── [프로젝트명]/
└── [컴포넌트명]/
├── assets/ # SVG, 이미지 에셋 (자동 다운로드)
├── screenshots/ # 구현물 스크린샷
│ └── impl.png
├── [컴포넌트명].html
└── [컴포넌트명].css
핵심 규칙
1. 추측 금지 원칙 (가장 중요!)
❌ 잘못된 접근:
- "이 정도면 비슷해 보이니까 완료"
- "대충 이 값이면 맞겠지"
- CSS 값을 "추측"해서 조정
✅ 올바른 접근:
- get_screenshot → 유일한 원본
- get_design_context → 정확한 구조와 수치
- Tailwind 클래스를 CSS로 변환할 때 값 그대로 사용
- 시각적 차이가 있으면 MCP 데이터 다시 확인
2. 에셋 규칙
| 규칙 | 설명 |
|---|---|
| 에셋 자동 다운로드 | dirForAssetWrites 파라미터 필수 |
| 로컬 경로 사용 | ./assets/파일명.svg 형식 |
| localhost URL 금지 | http://127.0.0.1:3845/... 직접 사용 금지 |
| 외부 아이콘 금지 | 새로운 아이콘 패키지 가져오기 금지 |
| Figma 페이로드만 | Figma에서 제공된 에셋만 사용 |
| 임의 생성 금지 | Figma에 없는 에셋 만들지 않음 |
3. 컨테이너 구조 패턴
<!-- Figma 선택 요소 = 컨테이너 -->
<div id="component-container">
<!-- Figma 내부 구조 그대로 -->
</div>
규칙:
- 컨테이너 크기 = Figma 선택 요소 크기 (metadata에서 확인)
- Figma 스타일 그대로 유지 (임의로 100%로 변경 금지)
4. overflow 적용 규칙
핵심 원칙: 동적 데이터가 렌더링되는 영역을 파악하여 적절한 위치에 overflow 적용
동적 데이터 영역 식별:
- 테이블의 목록 (list, tbody)
- 카드 목록 (card-list, grid)
- 반복 렌더링되는 아이템 컨테이너
/* 케이스 1: 내부 목록만 스크롤 */
.component-container {
overflow: hidden;
}
.component__list {
overflow-y: auto;
}
/* 케이스 2: 전체 컨테이너 스크롤 (컨테이너 자체가 동적 영역일 때) */
.component-container {
overflow: auto;
}
판단 기준:
- 컨테이너 내에 고정 헤더/푸터가 있고 목록만 스크롤 → 목록에 overflow
- 컨테이너 전체가 스크롤 대상 → 컨테이너에 overflow
5. box-sizing 주의사항
/* ❌ height 없으면 border가 별도 추가됨 */
.button {
box-sizing: border-box;
border: 1px solid #000;
padding: 6px 15px;
}
/* ✅ height 명시하면 border가 높이에 포함됨 */
.button {
box-sizing: border-box;
height: 24px; /* Figma에서 측정한 높이 명시 */
border: 1px solid #000;
padding: 6px 15px;
}
6. 레이아웃 컨테이너: flexbox 우선
레이아웃 컨테이너에는 position: absolute 대신 flexbox를 사용합니다.
/* ❌ absolute 레이아웃 */
.container {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
/* ✅ flexbox 레이아웃 */
.container {
display: flex;
flex-direction: column;
height: 100%;
}
.container__content {
flex: 1;
min-height: 0; /* overflow 스크롤 작동에 필요 */
}
absolute 허용 케이스:
- 배경 레이어 (
z-index: 0으로 분리) - 오버레이, 팝업
- 아이콘 내부 장식 요소
Playwright 스크린샷
node -e "
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage({
viewport: { width: 524, height: 350 } // Figma 프레임 크기와 동일
});
await page.goto('file:///path/to/component.html');
await page.screenshot({ path: './screenshots/impl.png' });
await browser.close();
})();
"
주의: viewport 크기를 Figma metadata의 프레임 크기와 정확히 일치시킬 것
금지 사항
❌ 추측하지 않는다
- "비슷해 보인다" ≠ "일치한다"
- 확인하지 않고 완료라고 말하지 않음
❌ 임의로 추가하지 않는다
- 외부 아이콘 패키지
- Figma에 없는 에셋
- 임의의 스타일
❌ 로컬호스트 URL 직접 사용
- http://127.0.0.1:3845/... URL을 HTML에 직접 사용
❌ 고정 사이즈 임의 변경
- Figma metadata에 명시된 크기 그대로 구현
❌ 스크린샷 비교 생략
- 매번 get_screenshot과 Playwright 결과 비교 필수
완료 체크리스트
- [ ] Figma 원본 스크린샷 확보 (get_screenshot)
- [ ] 에셋 자동 다운로드 완료 (dirForAssetWrites)
- [ ] 전체 컨테이너 크기가 Figma와 일치
- [ ] gap 값 정확 (row-gap ≠ column-gap 체크)
- [ ] 헤더-컨텐츠 간격 일치
- [ ] 상단/하단 여백 일치
- [ ] border 있는 요소에 height 명시
- [ ] 에셋 로컬 경로로 변환 완료
- [ ] Playwright 스크린샷 캡처 완료
- [ ] Figma 원본과 구현물 시각적 비교 완료
- [ ] 차이점 없음 확인
다음 단계
변환이 완료되면 create-component Skill을 사용하여 정적 HTML/CSS를 RNBT 동적 컴포넌트로 변환할 수 있습니다.