본문 바로가기
Graphic/SVG

Figma를 활용한 인터랙티브 SVG 제작 가이드

by curious week 2025. 9. 5.

Figma를 활용한 인터랙티브 SVG 제작 가이드


파트 I: Figma의 기본 원칙: 인터랙션을 위한 디자인

성공적인 인터랙티브 SVG 제작의 여정은 코드를 작성하기 훨씬 전, Figma 캔버스에서 시작됩니다. 이 첫 번째 파트에서는 인터랙션을 염두에 둔 디자인의 근본적인 원칙을 다룹니다. Figma를 단순한 시각적 디자인 도구가 아닌, 최종 웹 결과물의 구조적 청사진을 만드는 강력한 저작 도구로 바라보는 인식의 전환이 필요합니다. 모든 레이어, 그룹, 벡터 경로는 잠재적인 인터랙티브 요소가 되며, 이러한 관점은 디자인 프로세스 전반을 이끌어야 합니다.


1.1. 사고의 전환: 정적 목업에서 인터랙티브 설계도로

인터랙티브 SVG를 제작하는 과정은 단순히 보기 좋은 이미지를 그리는 것을 넘어섭니다. 이는 최종 제품에서 사용자와 상호작용할 컴포넌트의 구조적 기반을 설계하는 작업입니다. 핵심 철학은 Figma의 모든 디자인 요소가 코드에서 생명력을 얻을 잠재력을 가지고 있다는 점을 인지하는 것입니다.  

따라서 디자인 초기 단계부터 어떤 요소가 마우스 호버(hover)에 반응하고, 어떤 요소가 클릭(click)될 것이며, 스크롤에 따라 어떻게 움직일지 구체적으로 계획해야 합니다. 이 계획은 단순히 디자인이 끝난 후 추가하는 기능이 아니라, 레이어를 구성하고, 그룹을 만들고, 벡터를 분리하는 모든 디자인 결정의 기준이 되어야 합니다. 이러한 접근 방식은 정적인 시각 결과물과 동적인 사용자 경험 사이의 간극을 메우고, 후속 개발 과정을 훨씬 더 효율적으로 만듭니다.  


1.2. 인터랙티브 SVG의 해부학: 전략적 레이어링과 그룹화

Figma의 레이어 패널은 단순히 디자인 요소를 정리하는 공간이 아닙니다. 이것은 최종적으로 생성될 SVG 코드의 문서 객체 모델(DOM, Document Object Model)을 시각적으로 저작하는 강력한 도구입니다. Figma의 레이어 구조, 즉 프레임과 그룹은 SVG 코드 내에서 <svg>와 <g>(group) 태그로 직접 변환됩니다. 이 관계를 이해하는 것은 인터랙티브 SVG 제작의 핵심입니다.  

개발자는 웹 페이지의 요소를 찾고 조작하기 위해 DOM을 사용하며, HTML 문서에 삽입된 SVG는 이 DOM의 일부가 됩니다. 따라서 Figma에서 레이어를 어떻게 구성하고 그룹화하는지는 개발자(혹은 미래의 자신)가 해당 그래픽과 상호작용하기 위해 사용할 API를 정의하는 것과 같습니다. 체계적이지 않은 레이어 구조는 복잡하고 관리하기 어려운 SVG DOM으로 이어져, 인터랙션을 구현하는 것을 매우 어렵거나 불가능하게 만듭니다.

따라서 함께 움직이거나 동일한 인터랙션에 반응해야 하는 요소들은 반드시 하나의 그룹으로 묶어야 합니다. 예를 들어, 아이콘과 그에 해당하는 텍스트 라벨을 하나의 그룹으로 묶으면, 라벨에 마우스를 올렸을 때 아이콘의 색상을 변경하는 것과 같은 복합적인 효과를 CSS나 JavaScript로 쉽게 구현할 수 있습니다.  

.series:hover.bar와 같은 CSS 선택자는 Figma에서 적절한 그룹화를 했을 때만 가능해집니다. 이처럼 전략적인 그룹화는 코드의 복잡성을 줄이고, 유지보수가 용이한 구조를 만듭니다.  


1.3. 전략적 이름 지정 규칙: Figma 레이어에서 코드 선택자로

Figma 디자인과 코드를 연결하는 가장 중요하고 직접적인 기능은 SVG 내보내기 설정의 "id 속성 포함(Include 'id' attribute)" 옵션입니다. 이 설정을 활성화하면 Figma의 각 레이어 이름이 SVG 코드 내에서 고유한 id 속성으로 변환됩니다. 이는 인터랙션을 구현하는 데 있어 결정적인 역할을 합니다.  

레이어 이름이 id가 된다는 것은, 디자이너가 레이어 이름을 지정하는 행위가 곧 CSS 선택자(id 셀렉터)와 JavaScript 함수(예: document.getElementById())가 참조할 대상을 정의하는 과정임을 의미합니다. 따라서 명확하고 일관된 이름 지정 규칙을 수립하는 것이 매우 중요합니다.  

이름 지정 모범 사례:

  • 고유성: 모든 id는 문서 내에서 유일해야 합니다. Figma는 중복된 레이어 이름이 있을 경우, 유효한 XML 구조를 유지하기 위해 자동으로 _2, _3과 같은 접미사를 붙여주지만, 처음부터 고유한 이름을 부여하는 것이 혼란을 방지하는 가장 좋은 방법입니다.  
  • 서술성: 이름은 해당 레이어의 역할이나 내용을 명확하게 설명해야 합니다. 'Rectangle 52'와 같은 이름 대신 'cta-button-background'와 같이 서술적인 이름을 사용해야 합니다.
  • 코드 친화적 형식: CSS와 JavaScript에서 쉽게 사용할 수 있도록 케밥 케이스(kebab-case, 예: nav-button-icon)나 카멜 케이스(camelCase, 예: profileAvatarCircle)를 사용하는 것이 좋습니다. 공백이나 특수문자는 피해야 합니다.  

이 규칙을 따르면, Figma에서 cta-button이라는 이름의 레이어는 내보낸 SVG에서 <rect id="cta-button"... />가 되고, 이는 CSS에서 #cta-button 선택자로, JavaScript에서 document.getElementById('cta-button')으로 직접 제어할 수 있는 강력한 연결고리를 형성합니다.


1.4. 벡터 무결성: 애니메이션을 위한 요소 분리 기술

Figma에서 복잡한 아이콘을 디자인할 때 흔히 발생하는 문제 중 하나는, 여러 벡터 요소가 결합된 아이콘이 단 하나의 거대한 <path> 요소로 내보내지는 경우입니다. 이렇게 되면 아이콘의 특정 부분만 개별적으로 애니메이션하는 것이 불가능해집니다.  

이 문제를 해결하기 위해서는 디자인 단계에서부터 애니메이션을 고려하여 벡터를 의도적으로 분리해야 합니다. 이는 단순히 시각적으로 완성된 그래픽을 해체하고 재구성하는 과정이며, 다음과 같은 단계로 이루어집니다 :  

  1. 애니메이션 대상 식별: 아이콘의 어떤 부분을 개별적으로 움직일 것인지 먼저 결정합니다. 예를 들어, 위아래로 움직이는 두 개의 화살촉이 있는 아이콘이라면, 각 화살촉이 분리 대상입니다.
  2. 벡터 복제: 분리하려는 부분의 수만큼 원본 벡터 레이어를 복제합니다. 두 개의 화살촉을 분리하려면 원본을 한 번 복제하여 총 두 개의 동일한 벡터 레이어를 만듭니다.
  3. 불필요한 노드 삭제 (해체): 각 복제본에서 남기고자 하는 부분 외의 모든 벡터 노드(점)를 삭제합니다. 첫 번째 레이어에서는 위쪽 화살촉 노드만 남기고 나머지를 삭제하고, 두 번째 레이어에서는 아래쪽 화살촉 노드만 남기고 나머지를 삭제합니다.
  4. 레이어 이름 지정: 분리된 각 벡터 레이어에 'arrow-head-top', 'arrow-head-bottom'과 같이 의미 있는 이름을 부여합니다.

이러한 '구축-해체-재구축' 워크플로우는 인터랙티브 SVG 디자인이 비선형적인 과정임을 보여줍니다. 디자이너는 시각적으로 완벽한 형태를 만든 후, 애니메이션의 요구사항에 맞춰 이를 논리적 단위로 다시 해체해야 합니다. 내보내진 SVG 코드는 이 분리된 조각들을 통해 다시 시각적 전체를 구성하게 됩니다. 이는 정적 결과물을 위한 디자인과는 근본적으로 다른 접근 방식이며, 성공적인 SVG 애니메이션의 기반이 됩니다.


파트 II: SVG 내보내기 마스터하기

Figma에서 SVG를 내보내는 과정은 단순히 파일을 저장하는 행위가 아닙니다. 이것은 디자인을 코드로 변환하는 중요한 코드 생성 단계입니다. 이 파트에서는 내보내기 프로세스의 각 단계를 상세히 분석하고, 모든 설정이 최종 결과물의 인터랙션, 성능, 그리고 호환성에 어떤 영향을 미치는지 심층적으로 다룹니다.


2.1. 표준 내보내기 워크플로우: 단계별 가이드

Figma에서 SVG를 내보내는 기본 절차는 간단하며, 다음과 같은 단계로 이루어집니다.

  1. 객체 선택: 내보내고자 하는 프레임, 그룹, 또는 개별 레이어를 캔버스나 레이어 패널에서 선택합니다.  
  2. 내보내기 패널 접근: 화면 오른쪽의 속성 패널에서 '내보내기(Export)' 섹션을 찾습니다. 만약 보이지 않는다면 '+' 아이콘을 클릭하여 추가할 수 있습니다.  
  3. 형식 선택: 내보내기 설정에서 드롭다운 메뉴를 클릭하고 'SVG' 형식을 선택합니다.  
  4. 내보내기 실행: '내보내기 [레이어 이름]' 버튼을 클릭합니다. Figma 데스크톱 앱을 사용하는 경우 저장 위치를 묻는 대화 상자가 나타나고, 웹 브라우저를 사용하는 경우 브라우저의 기본 다운로드 폴더에 파일이 저장됩니다.  

여러 에셋을 한 번에 내보내려면, 각 에셋에 내보내기 설정을 추가한 후, Figma 메인 메뉴에서 파일(File) > 내보내기(Export)를 선택하거나 단축키(Mac: Shift + Command + E, Windows: Shift + Ctrl + E)를 사용하여 일괄적으로 내보낼 수 있습니다.  


2.2. 내보내기 설정 심층 분석: SVG 잠재력 잠금 해제

SVG 내보내기 패널에는 단순한 형식 선택 이상의 강력한 옵션들이 숨어 있습니다. 이 설정들은 최종 SVG 코드의 구조와 기능에 직접적인 영향을 미치므로, 각 옵션의 의미와 그에 따른 장단점을 정확히 이해하는 것이 중요합니다.

설정 기본값 기능 인터랙션 및 코드에 미치는 영향 인터랙티브 SVG를 위한 권장 사항
id 속성 포함 (Include "id" attribute) 비활성화 Figma 레이어 이름을 SVG 태그의 id 속성으로 변환합니다. 필수적입니다. 이 옵션이 없으면 CSS/JavaScript로 특정 요소를 타겟팅하기가 극도로 어려워집니다. 항상 활성화하십시오.  
 
 

텍스트 윤곽선 (Outline text) 활성화 텍스트 레이어를 벡터 경로(글리프)로 변환합니다. 텍스트 선택, 편집, 접근성을 비활성화하고 파일 크기를 증가시킵니다. 텍스트가 동적이거나 접근 가능해야 한다면 비활성화하십시오. 폰트 임베딩이 불가능한 순수 예술적 텍스트에만 활성화하십시오.  
 
 
 

획 단순화 (Simplify stroke) 활성화 내부/외부 획을 표준 중앙 획으로 변환합니다. 비활성화 시 더 복잡한 경로 데이터(마스크 및 채우기)를 생성하여 애니메이션을 어렵게 하고 파일 크기를 늘릴 수 있습니다. 비활성화해야만 해결되는 특정 시각적 렌더링 문제가 없는 한 활성화 상태를 유지하십시오.  
 

겹치는 레이어 무시 (Ignore overlapping layers) 비활성화 레이어의 보이는 부분만 내보냅니다. 출력을 단순화할 수 있지만, 다른 요소 뒤에서 슬라이드되어 나오는 등 애니메이션을 위해 의도된 요소의 일부를 제거할 수 있습니다. 주의해서 사용하십시오. 일반적으로 비활성화 상태를 유지하고 디자인 내에서 가시성을 관리하는 것이 좋습니다.

2.3. Figma의 SVG 출력물 이해하기: 코드에서 무엇을 기대할 수 있는가

Figma에서 내보낸 SVG 파일을 텍스트 편집기에서 열어보면, 디자인 요소가 어떻게 코드로 변환되었는지 확인할 수 있습니다. 이 구조를 이해하면 문제를 해결하고 코드를 직접 수정하는 데 도움이 됩니다.

  • 기본 구조: 최상위 프레임은 <svg> 태그가 됩니다. 이 태그에는 width, height, viewBox와 같은 속성이 포함되어 SVG의 크기와 좌표계를 정의합니다.  
  • 기본 도형: Figma의 사각형, 원, 타원, 선은 각각 <rect>, <circle>, <ellipse>, <line> 태그로 변환됩니다. 이러한 태그는 x, y, r, width, height 등 직관적인 속성을 가집니다.  
  • 복합 경로: 펜 툴로 그린 복잡한 도형, 불리언 연산을 거친 도형, 또는 대부분의 아이콘은 <path> 태그로 변환됩니다. <path>의 형태는 d 속성에 정의된 일련의 명령어로 결정됩니다. 이 데이터는 "M(ove to) 10 10 L(ine to) 20 20 Z(close path)"와 같은 형식으로, 복잡해 보이지만 벡터 드로잉의 수학적 표현일 뿐입니다.  
  • 그룹: Figma의 그룹과 프레임은 <g> 태그로 묶여 계층 구조를 유지합니다. 이는 앞서 설명한 바와 같이 스타일과 인터랙션을 그룹 단위로 적용하는 데 매우 유용합니다.

2.4. 일반적인 내보내기 함정과 비호환성 문제

Figma의 모든 시각적 기능이 SVG 형식으로 완벽하게 변환되는 것은 아닙니다. 내보내기 과정에서 발생할 수 있는 일반적인 문제들을 미리 인지하고 있어야 예상치 못한 결과를 피할 수 있습니다.

  • 지원되지 않는 효과: 배경 흐림(background blurs), 각진(angular) 또는 다이아몬드(diamond) 그라데이션과 같은 일부 고급 효과는 SVG 표준에서 지원하지 않습니다. Figma는 이러한 효과를 내보낼 때 래스터 이미지(비트맵)로 변환하거나, 방사형(radial) 그라데이션으로 대체합니다. 이 과정에서 벡터의 장점이 사라지거나 의도치 않은 시각적 변화가 발생할 수 있습니다.  
  • 래스터 이미지 포함: Figma 프레임 안에 PNG나 JPG 같은 래스터 이미지를 포함시킨 경우, 내보낸 SVG는 해당 이미지를 Base64로 인코딩하여 내부에 포함시킵니다. 이는 파일 크기를 급격히 증가시키고, 다른 벡터 편집 프로그램(예: Adobe Illustrator)에서 SVG를 열었을 때 이미지가 누락되는 원인이 될 수 있습니다.  
  • 렌더링 규칙 차이 (Fill-Rule): Figma는 겹치는 경로의 내부를 채우는 방식을 결정할 때 'even-odd' 규칙을 기본으로 사용합니다. 하지만 많은 브라우저와 다른 도구들은 'non-zero' 규칙을 기본값으로 사용합니다. 이 차이 때문에 Figma에서는 정상적으로 보이던 복잡한 도형(예: 구멍 뚫린 모양)이 웹에서는 의도치 않게 채워져 보일 수 있습니다. 이 문제는 "Fill Rule Editor"와 같은 플러그인을 사용하여 내보내기 전에 벡터 경로의 방향을 조정함으로써 해결할 수 있습니다.  

파트 III: CSS로 SVG에 생명 불어넣기

SVG를 성공적으로 내보냈다면, 이제 인터랙션의 첫 단계를 구현할 차례입니다. CSS는 SVG에 스타일을 적용하고, 호버 효과를 추가하며, 간단하면서도 효과적인 애니메이션을 만드는 가장 직접적이고 효율적인 방법입니다. 이 파트에서는 SVG에 CSS를 적용하는 다양한 방법과 일반적인 문제 해결책을 포함한 실용적인 기법들을 다룹니다.


3.1. SVG에 CSS를 적용하는 방법

SVG에 CSS 스타일을 적용하는 방법은 크게 세 가지가 있으며, 사용 사례에 따라 적절한 방법을 선택해야 합니다.

  • 인라인 스타일 (Inline Styles): SVG 요소의 style 속성 안에 직접 CSS 속성을 기술하는 방식입니다. 특정 요소에만 고유한 스타일을 빠르게 적용할 때 유용하지만, 재사용성이 낮고 코드가 지저분해질 수 있습니다.
<circle cx="50" cy="50" r="40" style="fill:blue; stroke:black;"/>
  • 내부 스타일시트 (Internal Stylesheet): <svg> 태그 내부에 <style> 블록을 포함시키는 방법입니다. 이 방식은 SVG 파일 자체에 스타일 정보가 포함되므로 이식성이 높고, CSS 클래스와 ID를 사용하여 여러 요소를 효율적으로 관리할 수 있습니다. 인터랙티브 SVG에 가장 일반적으로 권장되는 방법 중 하나입니다.  
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
  <style>
   .my-circle {
      fill: gold;
      stroke: maroon;
    }
  </style>
  <circle class="my-circle" cx="50" cy="50" r="40" />
</svg>
  • 외부 스타일시트 (External Stylesheet): 별도의 .css 파일을 연결하는 방식입니다. 이 방법은 SVG가 HTML 문서 내에 직접 삽입(인라인 SVG)된 경우에만 작동합니다. <img>나 <object> 태그로 SVG를 삽입하면 외부 CSS가 적용되지 않습니다. 인라인 SVG의 경우, HTML의 <link> 태그나 SVG 내부의 @import 규칙을 사용하여 외부 스타일시트를 연결할 수 있습니다. 이 방식은 웹사이트 전체의 스타일을 일관되게 관리할 때 유용합니다.  

3.2. 인터랙티브 상태 만들기: Hover, Focus, Active 효과

CSS의 가상 클래스(pseudo-classes)를 사용하면 사용자 상호작용에 따라 SVG의 스타일을 동적으로 변경할 수 있습니다.

가장 흔한 예는 :hover를 사용하여 마우스 커서가 요소 위에 올라왔을 때 스타일을 바꾸는 것입니다. fill(채우기 색), stroke(선 색), opacity(투명도) 등의 속성을 변경하여 시각적 피드백을 제공할 수 있습니다.  

또한, Figma에서 전략적으로 그룹화한 요소를 활용하면 더 복잡한 인터랙션을 구현할 수 있습니다. 예를 들어, 막대 차트에서 특정 라벨(label) 위에 마우스를 올렸을 때, 해당 라벨과 연결된 막대(bar)를 강조 표시할 수 있습니다.  

/* 'chart-group' ID를 가진 그룹 내의 막대에 대한 기본 스타일 */
#chart-group.bar {
  fill: #3498db;
  transition: fill 0.3s ease;
}

/* 그룹에 호버했을 때, 그 안의 막대 스타일 변경 */
#chart-group:hover.bar {
  fill: #2980b9;
}

/* 그룹에 호버했을 때, 그 안의 라벨 스타일 변경 */
#chart-group:hover.label {
  font-weight: bold;
}

3.3. CSS 트랜지션과 키프레임으로 애니메이션하기

CSS는 정적인 상태 변화를 넘어 부드러운 애니메이션을 구현하는 두 가지 강력한 도구를 제공합니다: 트랜지션(Transitions)과 키프레임 애니메이션(Keyframe Animations).

  • 트랜지션 (Transitions): transition 속성은 한 상태에서 다른 상태로 변화할 때 중간 과정을 부드럽게 만들어줍니다. 예를 들어, 호버 시 색상이 즉시 바뀌는 대신 서서히 변하도록 할 수 있습니다. 여기서 흔히 발생하는 문제점은 fill 속성에 트랜지션이 적용되지 않는 경우입니다. 이는 대부분 초기 fill 색상이 SVG의 프레젠테이션 속성(예: fill="#FAFAFA")으로 지정되었기 때문입니다. CSS 트랜지션이 작동하려면, 초기 상태와 최종 상태 모두 CSS에 의해 제어되어야 합니다. 따라서 초기 fill 값도 CSS 규칙이나 인라인 style 속성으로 지정해야 합니다.  
  • 키프레임 애니메이션 (Keyframe Animations): @keyframes 규칙을 사용하면 시작과 끝 상태뿐만 아니라 애니메이션의 여러 중간 단계를 정의하여 더 복잡하고 정교한 움직임을 만들 수 있습니다. 예를 들어, 아이콘이 계속해서 회전하거나 깜박이는 효과를 구현할 수 있습니다. 회전이나 크기 조절 같은 transform 애니메이션을 적용할 때는 transform-origin 속성을 설정하는 것이 매우 중요합니다. 이 속성은 변형의 기준점(축)을 지정하며, 이를 올바르게 설정해야 자연스러운 움직임을 얻을 수 있습니다.  
/* 회전 애니메이션의 기준점을 중앙으로 설정 */
#gear-icon {
  transform-origin: center;
}

/* 'spin'이라는 이름의 키프레임 애니메이션 정의 */
@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

/* SVG 컨테이너에 호버했을 때, #gear-icon에 spin 애니메이션 적용 */
#interactive-container:hover #gear-icon {
  animation: spin 2s linear infinite;
}

3.4. 실용 예제: 아이콘 및 UI 요소 애니메이션

지금까지 배운 개념들을 통합하여 실제 예제에 적용해 보겠습니다.

  • 바운스 화살표 아이콘: 파트 I에서 벡터를 분리하여 만든 화살표 아이콘에 간단한 호버 애니메이션을 적용할 수 있습니다. 마우스를 올리면 아래쪽 화살표가 살짝 아래로, 위쪽 화살표가 살짝 위로 움직이는 효과를 transform: translateY()와 transition을 사용하여 구현할 수 있습니다.  
  • 모핑 호버 효과: SVG 필터와 transition을 결합하여 도형의 모양이 부드럽게 변하는 듯한 모핑 효과를 만들 수 있습니다. 이는 사용자의 흥미를 유발하는 독특한 마이크로 인터랙션을 제공합니다.  

이러한 예제들은 CSS만으로도 얼마나 풍부하고 동적인 사용자 경험을 만들어낼 수 있는지를 보여줍니다. 다음 파트에서는 JavaScript를 사용하여 이보다 더 높은 수준의 인터랙션을 구현하는 방법을 살펴보겠습니다.


파트 IV: JavaScript를 활용한 고급 인터랙션

CSS가 선언적인 스타일과 상태 변화에 강점을 보인다면, JavaScript는 동적인 데이터 처리, 복잡한 사용자 입력, 그리고 조건부 로직을 통해 인터랙션의 한계를 확장합니다. 이 파트에서는 JavaScript를 사용하여 SVG를 완전히 제어하고, 사용자와 실시간으로 상호작용하는 정교한 그래픽을 만드는 방법을 탐구합니다.


4.1. 스크립팅을 위한 SVG 임베딩: 결정적 선택

JavaScript로 SVG 내부 요소를 제어하기 위해서는 SVG를 HTML 문서에 어떻게 포함시킬지 신중하게 결정해야 합니다. 이 선택은 인터랙션의 가능 범위를 결정하는 가장 중요한 요소입니다.

결론부터 말하자면, 완전한 인터랙션을 위해서는 SVG를 인라인(inline)으로 삽입해야 합니다. 웹 브라우저는 동일 출처 정책(Same-Origin Policy)이라는 보안 규칙을 적용합니다. 이 때문에 <img>, background-image, 심지어 <object>나 <iframe> 태그를 통해 외부 파일로 SVG를 로드하면, 해당 SVG의 내부 DOM은 메인 HTML 문서로부터 격리된 '샌드박스' 상태가 됩니다. 이 샌드박스는 보안상의 이유로 메인 문서의 JavaScript가 SVG 내부의 개별 <path>나 <circle> 요소에 접근하여 조작하는 것을 차단합니다.  

오직 <svg>...</svg> 코드를 HTML 문서에 직접 붙여넣는 '인라인' 방식만이 SVG를 메인 문서 DOM의 일부로 만듭니다. 이렇게 해야만 JavaScript가 SVG 내부의 모든 요소에 자유롭게 접근하여 이벤트 리스너를 추가하고 속성을 변경하는 등의 조작을 할 수 있습니다. 따라서 SVG 임베딩 방법의 선택은 사소한 구현 디테일이 아니라, 인터랙션의 잠재력을 결정하는 근본적인 아키텍처 설계 문제입니다.

임베딩 방법 장점 단점 인터랙션 수준
인라인 <svg> 완전한 CSS/JS 제어 가능, HTTP 요청 없음 HTML 파일이 길어지고 복잡해짐, 캐싱 불가 최상
<object> 외부 파일로 분리, 캐싱 가능, 스크립팅 일부 가능 스크립팅 접근이 복잡함 (.contentDocument), CSS 제약 중간
<img> 가장 간단하고 널리 지원됨, 캐싱 가능 CSS/JS로 내부 조작 절대 불가 없음
CSS background-image 순수 장식용으로 적합, CSS로 제어 CSS/JS로 내부 조작 절대 불가 없음

4.2. SVG DOM: 요소 선택 및 조작

인라인으로 삽입된 SVG의 요소들은 일반 HTML 요소와 동일한 방식으로 선택하고 조작할 수 있습니다.

  • 요소 선택: Figma 레이어 이름에서 파생된 id를 사용하여 document.getElementById()로 특정 요소를 직접 선택하는 것이 가장 효율적입니다. 또는 document.querySelector()나 document.querySelectorAll()을 사용하여 클래스 이름이나 태그 이름으로 요소를 선택할 수도 있습니다.  
const myButton = document.getElementById('cta-button');
const allCircles = document.querySelectorAll('.icon-circle');
  • 속성 조작: SVG 요소의 속성(예: cx, cy, d)을 변경할 때는 element.setAttributeNS(null, 'attributeName', 'value')를 사용하는 것이 표준입니다. null 네임스페이스는 대부분의 경우에 잘 작동합니다. CSS 속성을 변경할 때 element.style.setProperty('opacity', '0.5')를 사용합니다.  
const circle = document.getElementById('profile-avatar-circle');
circle.setAttributeNS(null, 'r', '50'); // 반지름을 50으로 변경
circle.style.setProperty('fill', 'var(--primary-color)'); // 채우기 색을 CSS 변수로 변경
  • <object> 태그 내 SVG 조작: <object> 태그를 사용해야 하는 드문 경우, 내부 SVG에 접근하려면 먼저 <object> 요소를 선택한 후 .contentDocument 속성을 통해 내부 문서에 접근해야 합니다. 이 작업은 SVG가 완전히 로드된 후에 실행되어야 하므로, window의 load 이벤트 리스너 내에서 수행하는 것이 안전합니다.  

4.3. 이벤트 핸들링: 클릭, 마우스 움직임 등에 반응하기

JavaScript 이벤트 리스너를 사용하면 사용자의 다양한 행동에 실시간으로 반응하는 SVG를 만들 수 있습니다.

  • 클릭 이벤트: element.addEventListener('click',...)를 사용하여 SVG 요소에 클릭 이벤트를 추가할 수 있습니다. 상태를 추적하기 위해 외부 변수(예: let lightOn = true;)를 사용하는 것이 일반적인 패턴입니다. 이 변수는 클릭할 때마다 상태를 토글(toggle)하여 다른 동작을 수행하도록 합니다.  
const lightBulb = document.getElementById('bulb-path');
let isLightOn = false;

lightBulb.addEventListener('click', () => {
  isLightOn =!isLightOn; // 상태 토글
  const newColor = isLightOn? 'yellow' : '#333';
  lightBulb.setAttributeNS(null, 'fill', newColor);
});
  • 마우스 이벤트: mousedown, mousemove, mouseup 이벤트를 조합하여 드래그 앤 드롭과 같은 복잡한 인터랙션을 구현할 수 있습니다. 예를 들어, 램프의 머리 부분을 드래그하여 각도를 조절하는 인터랙티브 램프를 만들 수 있습니다.  
  • 기타 이벤트: SVG는 mouseover, mouseout, 키보드 이벤트 등 W3C에서 정의한 다양한 UI 이벤트를 지원하여 풍부한 상호작용을 구현할 수 있습니다.  

4.4. 동적 SVG: 프로그래밍 방식으로 요소 생성 및 애니메이션

JavaScript를 사용하면 기존 SVG를 조작하는 것을 넘어, 완전히 새로운 SVG 요소를 동적으로 생성하고 애니메이션을 적용할 수 있습니다.

  • 요소 생성: document.createElementNS('http://www.w3.org/2000/svg', 'tagName')을 사용하여 새로운 SVG 요소를 만듭니다. 여기서 SVG 네임스페이스(http://www.w3.org/2000/svg)를 지정하는 것이 중요합니다. 생성된 요소에 속성을 설정한 후, parentElement.appendChild()를 사용하여 SVG에 추가합니다.  
  • 애니메이션 루프: window.requestAnimationFrame()은 브라우저의 렌더링 주기에 맞춰 애니메이션을 실행하여 부드럽고 성능이 뛰어난 움직임을 구현하는 핵심적인 방법입니다. 이 함수는 콜백 함수를 인자로 받아 다음 프레임을 그리기 직전에 실행합니다. 콜백 함수 내에서 요소의 속성을 조금씩 변경하고 다시 requestAnimationFrame()을 호출하는 재귀적인 구조를 통해 애니메이션 루프를 만듭니다.  

4.5. SVG 애니메이션 라이브러리 소개

바닐라 JavaScript로 모든 것을 구현할 수 있지만, 복잡한 애니메이션의 경우 전문 라이브러리를 사용하면 개발 속도와 코드의 안정성을 크게 향상시킬 수 있습니다.

  • GSAP (GreenSock Animation Platform): 웹 애니메이션의 산업 표준으로 여겨지는 강력한 라이브러리입니다. 복잡한 시퀀싱, 타임라인 제어, 뛰어난 성능을 제공하며 SVG 애니메이션을 매우 쉽게 만들어 줍니다.  
  • SVG.js: SVG 조작과 애니메이션에 특화된 경량 라이브러리입니다. 더 간결한 문법으로 SVG 요소를 생성하고 애니메이션을 적용할 수 있도록 도와줍니다.  

이러한 라이브러리들은 복잡한 수학 계산이나 requestAnimationFrame 루프 관리를 추상화하여 개발자가 애니메이션의 창의적인 측면에 더 집중할 수 있게 해줍니다.


파트 V: 더 넓은 생태계: 도구, 플러그인, 그리고 대안

Figma에서 시작하여 코드로 완성하는 핵심 워크플로우는 강력하지만, 이것이 전부는 아닙니다. 전문적인 작업 환경에서는 생산성을 높이고 결과물의 품질을 향상시키기 위해 다양한 도구와 기술을 조합하여 사용합니다. 이 파트에서는 Figma 플러그인, 외부 전문 도구, 그리고 인터랙티브 SVG의 대안 기술들을 비교 분석하여 프로젝트의 요구사항에 가장 적합한 기술 스택을 선택할 수 있도록 안내합니다.


5.1. Figma 플러그인을 활용한 워크플로우 간소화

Figma 자체의 기능만으로도 훌륭한 기반을 다질 수 있지만, Figma 커뮤니티와 서드파티 개발자들이 제공하는 플러그인 생태계는 작업 과정을 혁신적으로 단축하고 결과물의 수준을 한 단계 끌어올립니다.

  • 애니메이션 플러그인:
    • Figmotion: Figma 내에서 직접 타임라인 기반 애니메이션을 제작할 수 있는 도구입니다. 프레임을 선택하고, 타임라인에 위치, 크기, 투명도 등의 속성에 대한 키프레임을 추가하여 애니메이션을 만듭니다. 결과물은 CSS 또는 JSON 형식으로 내보낼 수 있어 개발자와의 협업에 유용합니다.  
    • LottieFiles: 복잡하고 정교한 애니메이션을 제작하고 관리하는 데 가장 널리 사용되는 플러그인입니다. 디자이너는 LottieFiles 플러그인을 사용하여 방대한 애니메이션 라이브러리에 접근하거나, 직접 만든 디자인을 Lottie 애니메이션(JSON 형식)으로 변환할 수 있습니다. 이는 특히 로딩 스피너, 온보딩 애니메이션 등 정해진 시나리오를 가진 풍부한 모션 그래픽에 적합합니다.  
  • 유틸리티 플러그인:
    • Anima: Figma 디자인에 호버 효과, 입력 필드, 동영상 등을 추가하여 고품질 프로토타입을 만들고, 이를 HTML/CSS 코드로 직접 내보낼 수 있게 해주는 강력한 플러그인입니다.  
    • SVG Export / TinyImage: Figma의 기본 내보내기 기능보다 더 세밀한 제어와 최적화 옵션을 제공하는 플러그인들입니다. 코드 정리, 파일 크기 압축 등을 통해 웹 성능을 향상시키는 데 도움을 줍니다.  

5.2. 외부 애니메이션 및 최적화 도구

때로는 Figma를 벗어나 전문적인 외부 도구를 사용하는 것이 더 효율적일 수 있습니다.

  • SVGator: SVG 애니메이션 제작에 특화된 웹 기반 도구입니다. 코딩 없이 직관적인 타임라인 인터페이스를 통해 복잡한 애니메이션을 만들 수 있습니다. Figma에서 만든 정적 SVG를 가져와 생명을 불어넣는 방식으로 작동합니다. 장점은 사용이 쉽고 별도의 코딩 지식이 필요 없다는 점이며, 단점은 새로운 도구를 배워야 하고 유료 구독이 필요할 수 있다는 점입니다.  
  • SVGOMG: 웹 성능 최적화를 위한 필수 도구입니다. Figma에서 내보낸 SVG 파일에는 불필요한 메타데이터, 편집기 전용 정보, 긴 소수점 자리 등 파일 크기를 늘리는 요소들이 포함되어 있습니다. SVGOMG는 웹 인터페이스를 통해 이러한 불필요한 데이터를 제거하고, 경로를 최적화하여 파일 크기를 극적으로 줄여줍니다. 웹에 배포하기 전 마지막 단계로 SVGOMG를 거치는 것은 매우 좋은 습관입니다.  

5.3. 기술 비교 분석: 인터랙티브 SVG vs. Lottie vs. Figma 프로토타입

'인터랙티브한 무언가'를 만들고 싶을 때, 어떤 기술을 선택해야 할까요? Figma 프로토타입, 직접 코딩하는 인터랙티브 SVG, 그리고 Lottie 애니메이션은 각기 다른 목적과 장단점을 가집니다. 프로젝트의 목표에 맞는 올바른 도구를 선택하는 것은 매우 중요합니다.

기능 Figma 프로토타입 인터랙티브 SVG (CSS/JS) Lottie 애니메이션
주요 사용 사례 사용자 흐름 검증, 화면 전환 중심의 클릭 가능한 목업. 고품질 마이크로 인터랙션, 데이터 시각화, 인터랙티브 아이콘. 복잡하고 미리 정의된 애니메이션 (예: 로딩 스피너, 캐릭터 애니메이션).
인터랙션 수준 낮음. 클릭, 호버, 드래그를 통한 정적 화면 간의 전환만 가능. 실제 로직이나 데이터 입력은 불가능합니다.  
 
 
 

높음. JavaScript를 통해 동적 데이터, 복잡한 로직, 이벤트 핸들링 등 완전한 제어가 가능합니다.  
 
 

중간. 코드로 재생, 정지, 탐색 등을 제어하고 스크롤과 같은 이벤트에 반응할 수 있지만, 애니메이션 자체는 미리 정의되어 있습니다.  
 
 

성능 웹 에셋이 아니므로 해당 없음. 간단한 그래픽에 대해 매우 우수함. 성능은 그래픽의 복잡성과 JavaScript 코드의 효율성에 따라 달라집니다. 매우 우수함. 고도로 최적화된 JSON 형식으로, 복잡한 벡터 애니메이션의 경우 GIF나 비디오보다 파일 크기가 훨씬 작고 성능이 뛰어납니다.  
 
 

개발 노력 낮음. 모든 작업이 Figma 내에서 이루어집니다. 중간 ~ 높음. CSS 및/또는 JavaScript에 대한 지식이 필요합니다. 중간. After Effects나 Figma 플러그인 같은 애니메이션 도구와 코드에 플레이어 라이브러리를 설치해야 합니다.
가장 적합한 경우... 사용자 여정이나 레이아웃을 빠르게 테스트할 때. 호버 시 변하는 버튼, 인터랙티브 차트, 클릭 시 애니메이션되는 아이콘. 상세한 온보딩 애니메이션, 축하 효과, 움직이는 일러스트레이션.

이 표는 모호한 '인터랙션' 요구사항을 구체적이고 정당한 기술 선택으로 이끌어주는 의사결정 프레임워크를 제공합니다.


파트 VI: 전문 워크플로우: 최적화, 접근성 및 문제 해결

전문적인 웹 개발에서 아름답고 기능적인 결과물을 만드는 것만큼 중요한 것은, 그 결과물이 빠르고, 모든 사용자가 접근 가능하며, 견고하게 작동하도록 만드는 것입니다. 이 마지막 파트에서는 제작한 인터랙티브 SVG를 전문가 수준으로 끌어올리기 위한 최적화, 접근성 확보, 그리고 일반적인 문제 해결 방안을 다룹니다.


6.1. SVG 성능 공학: 최소화 및 최적화

SVG는 벡터 기반이므로 본질적으로 가볍지만, 디자인 도구에서 생성된 코드는 종종 불필요한 정보를 포함하여 파일 크기를 늘리고 렌더링 성능을 저하시킬 수 있습니다.

  • 수동 최적화: 텍스트 편집기에서 SVG 코드를 직접 수정하여 최적화할 수 있습니다. 주요 기법은 다음과 같습니다 :  
    • 주석 및 메타데이터 제거: Figma나 다른 편집기가 추가한 주석(``), 메타데이터(<metadata>) 태그를 삭제합니다.
    • 경로 데이터 단순화: <path>의 d 속성에 있는 소수점 값을 2-3자리로 반올림하여 정밀도를 낮추면 파일 크기를 줄일 수 있습니다.
    • 불필요한 그룹 제거: 내용이 없거나 변환 효과가 없는 빈 <g> 태그를 제거합니다.
  • 자동 최적화: 수동 최적화는 번거롭고 실수가 발생하기 쉽습니다. SVGOMG (SVGO의 웹 GUI 버전)와 같은 자동화 도구를 사용하는 것이 훨씬 효율적입니다. 이 도구는 SVG 파일을 업로드하기만 하면 위에서 언급한 최적화 기법들을 자동으로 적용하여 파일 크기를 크게 줄여줍니다. 배포 전 최종 단계로 SVGOMG를 사용하는 것은 거의 필수적인 과정입니다.  
  • 고급 기법:
    • SVG 스프라이트: 여러 개의 아이콘 SVG를 하나의 파일로 결합하는 기법입니다. <symbol> 태그로 각 아이콘을 정의하고 <use> 태그로 필요할 때마다 불러와 사용합니다. 이를 통해 HTTP 요청 수를 줄여 로딩 성능을 개선할 수 있습니다.  
    • 지연 로딩 (Lazy Loading): 페이지의 핵심 콘텐츠가 아닌 SVG(예: 페이지 하단의 일러스트레이션)는 사용자가 해당 영역으로 스크롤할 때까지 로딩을 지연시켜 초기 페이지 로드 속도를 향상시킬 수 있습니다.  

6.2. 인터랙티브 SVG의 접근성(a11y) 확보

웹 접근성은 모든 사용자가 정보와 기능에 동등하게 접근할 수 있도록 보장하는 것입니다. 인터랙티브 SVG 역시 이 원칙에서 예외가 아닙니다.

  • 장식용 vs. 정보성 SVG 구분:
    • 순전히 시각적 장식을 위해 사용되는 SVG(예: 배경 패턴)는 스크린 리더와 같은 보조 기술에 의해 무시되어야 합니다. aria-hidden="true" 속성을 추가하여 접근성 트리에서 숨길 수 있습니다.  
    • 정보를 전달하거나 특정 기능을 수행하는 SVG(예: 차트, 클릭 가능한 아이콘)는 반드시 접근 가능해야 합니다.
  • 스크린 리더를 위한 정보 제공:
    • <title> 요소: SVG에 대한 간결한 제목을 제공합니다. 스크린 리더는 이 제목을 읽어 사용자에게 SVG의 내용을 알려줍니다.
    • <desc> 요소: 더 긴 설명이 필요할 경우 사용합니다.
    • aria-labelledby와 aria-describedby: <title>과 <desc> 요소에 id를 부여하고, 최상위 <svg> 태그에서 이 id들을 참조하여 명시적으로 연결하는 것이 가장 견고한 방법입니다.
  • 키보드 접근성:
    • 마우스를 사용할 수 없는 사용자를 위해 모든 인터랙티브 요소는 키보드로 접근하고 조작할 수 있어야 합니다.
    • tabindex="0": 클릭 가능한 SVG 요소에 이 속성을 추가하면 키보드의 Tab 키로 포커스를 받을 수 있게 됩니다.
    • ARIA 역할 및 상태: SVG 요소가 어떤 역할을 하는지 보조 기술에 알려주어야 합니다. 예를 들어, 클릭 가능한 아이콘에는 role="button"을 추가하고, 토글 버튼의 경우 상태에 따라 aria-pressed="true" 또는 aria-pressed="false"를 동적으로 변경해주어야 합니다.  

6.3. 일반적인 문제 진단 및 해결

인터랙티브 SVG를 제작하다 보면 다양한 문제에 직면할 수 있습니다. 다음은 일반적인 문제와 그 해결책입니다.

  • 렌더링 문제:
    • "SVG가 보이지 않거나 크기가 0x0입니다": 대부분의 경우 <svg> 태그에 width와 height 속성 또는 viewBox 속성이 누락되었기 때문입니다. 이 속성들을 명시적으로 지정하면 해결됩니다.  
    • "둥근 모서리가 각지게 보입니다": Figma의 SVG 내보내기 렌더링 문제입니다. 모서리 반경(corner radius)을 정수 값으로 사용하거나, 내보내기 전에 도형을 평면화(Flatten)하거나 획을 윤곽선으로(Outline Stroke) 변환하면 해결될 수 있습니다.  
  • 내보내기 문제:
    • "SVG 내부의 이미지가 누락됩니다": SVG 형식은 래스터 이미지(PNG, JPG) 포함을 일관되게 지원하지 않습니다. 특히 다른 벡터 편집 프로그램에서 열 때 문제가 발생합니다. 해결책은 이미지를 포함한 디자인을 PDF로 내보낸 후, 해당 PDF를 다른 프로그램에서 다시 SVG로 변환하는 것입니다.  
  • 인터랙션 문제:
    • "CSS 호버 효과가 부드럽게 전환되지 않습니다": 요소의 초기 상태(예: fill 색상)가 SVG의 프레젠테이션 속성으로 지정되어 있기 때문일 가능성이 높습니다. 초기 상태도 CSS(인라인 style 또는 스타일시트)로 지정해야 transition이 작동합니다.  
    • "JavaScript가 요소를 찾지 못합니다 (null 반환)": SVG가 <img>나 background-image로 삽입되었기 때문입니다. 스크립트로 내부 요소를 제어하려면 반드시 SVG를 HTML에 인라인으로 삽입해야 합니다.  

결론 및 권장 사항

이 가이드는 Figma를 사용하여 정적 디자인에서 완전한 인터랙티브 SVG를 제작하는 전 과정을 심도 있게 다루었습니다. 성공적인 결과물을 위해서는 디자인 단계부터 최종 배포까지, 기술적 원칙과 전문적인 워크플로우를 일관되게 적용하는 것이 중요합니다.


7.1. 핵심 요약 및 모범 사례

  • 인터랙션을 위해 디자인하라: 디자인 초기부터 어떤 요소가 어떻게 상호작용할지 계획하고, 그 계획에 따라 레이어 구조를 설계해야 합니다.
  • 레이어 이름을 신중하게 지정하라: 모든 인터랙티브 요소의 레이어 이름은 고유하고 서술적이며 코드 친화적인 형식이어야 합니다. 이는 코드와의 가장 직접적인 연결고리입니다.
  • id 속성 포함 설정을 활성화하라: Figma에서 SVG를 내보낼 때 이 옵션을 활성화하는 것은 인터랙션 구현의 필수 전제 조건입니다.
  • 스크립팅을 위해 인라인하라: JavaScript로 SVG 내부 요소를 제어해야 한다면, 다른 임베딩 방법 대신 반드시 HTML에 SVG 코드를 직접 삽입(인라인)해야 합니다.
  • 배포 전에 최적화하라: SVGOMG와 같은 도구를 사용하여 불필요한 데이터를 제거하고 파일 크기를 최소화하여 웹 성능을 향상시켜야 합니다.
  • 접근성을 항상 테스트하라: 모든 인터랙티브 SVG는 스크린 리더 사용자와 키보드 사용자도 동등하게 경험할 수 있도록 <title>, role, tabindex 등의 접근성 속성을 갖추어야 합니다.

7.2. 프로젝트에 맞는 올바른 접근법 선택하기

모든 프로젝트에 동일한 기술이 최선은 아닙니다. 프로젝트의 목표와 요구사항에 따라 가장 적합한 도구와 기술을 선택하는 것이 현명합니다. 다음 의사 결정 흐름은 올바른 방향을 제시해 줄 것입니다.

  1. 프로젝트의 주요 목표는 무엇인가?
    • A) 사용자 흐름 및 화면 전환 검증: 사용자가 특정 작업을 완료하는 과정을 테스트하는 것이 주 목적이라면, 코딩 없이 빠르고 효율적으로 제작할 수 있는 Figma 프로토타입이 가장 적합합니다.
    • B) UI 요소에 생동감 부여 또는 데이터 시각화: 버튼의 호버 상태, 아이콘의 클릭 애니메이션, 데이터에 반응하는 차트 등 고품질의 실시간 인터랙션이 필요하다면, CSS/JavaScript를 사용한 인터랙티브 SVG가 최상의 선택입니다.
    • C) 복잡하고 서사적인 애니메이션 구현: 온보딩 과정의 캐릭터 애니메이션이나 정교한 로딩 화면과 같이 미리 정해진 시나리오를 가진 풍부한 모션 그래픽이 필요하다면, Lottie 애니메이션이 가장 효율적이고 성능이 뛰어난 솔루션입니다.

이 가이드에서 제시된 원칙과 기법들을 숙지하고 프로젝트의 맥락에 맞게 적용함으로써, 여러분은 정적인 디자인을 넘어 사용자의 참여를 유도하고 깊은 인상을 남기는 동적인 웹 경험을 창조할 수 있을 것입니다.

'Graphic > SVG' 카테고리의 다른 글

SVG(1)  (0) 2025.09.22
SVG 가이드  (2) 2025.09.05
SVG 이해하기  (5) 2025.08.16