Variants와 상태 설계로 디자인 시스템 시작하기
반복 UI의 다음 단계, Variants
지난 장에서 우리는 버튼, 입력창, 카드처럼 반복해서 쓰는 UI를 Components로 만들었습니다. 컴포넌트는 "한 번 잘 만들어 두고 여러 곳에서 복사해 쓰는 원본"입니다. 그런데 실무 화면을 만들다 보면 금방 이런 상황을 만나게 됩니다.
버튼 하나만 봐도 기본 버튼, 비활성 버튼, 눌린 버튼, 아이콘이 있는 버튼, 작은 버튼, 큰 버튼이 필요합니다. 입력창도 마찬가지입니다. 아무것도 입력하지 않은 상태, 포커스된 상태, 에러가 난 상태, 입력이 완료된 상태가 있습니다. 이때 모든 상태를 각각 다른 컴포넌트로 흩어 놓으면 어느 순간 파일 안이 "버튼_최종", "버튼_최종2", "진짜최종버튼" 같은 이름으로 가득 차기 시작합니다.
Variants는 이런 혼란을 정리하기 위한 기능입니다. 같은 역할을 하는 컴포넌트의 여러 모양과 상태를 하나의 묶음으로 관리하게 해 줍니다. 버튼이라면 버튼끼리, 입력창이라면 입력창끼리 모아 두고, 오른쪽 패널에서 옵션을 바꾸듯 Primary, Disabled, Large 같은 상태를 선택할 수 있습니다.
이 장에서는 Variants를 단순히 "컴포넌트를 묶는 기능"으로만 보지 않겠습니다. 디자이너, 기획자, 개발자가 같은 기준으로 이야기할 수 있는 상태 설계의 출발점으로 다루겠습니다.

Variants를 이해하는 네 가지 단어
Variants를 처음 보면 Property, Value, Variant, Set 같은 말이 한꺼번에 등장해서 어렵게 느껴질 수 있습니다. 하지만 쇼핑몰에서 옷을 고르는 장면으로 생각하면 금방 이해됩니다.
티셔츠를 살 때 우리는 색상, 사이즈, 핏을 고릅니다. 예를 들어 색상은 검정, 흰색, 파랑 중 하나이고, 사이즈는 S, M, L 중 하나입니다. 피그마의 Variants도 이와 비슷합니다.
| 개념 | 쉬운 의미 | 버튼 예시 |
|---|---|---|
| Component Set | 같은 컴포넌트 변형을 모아 둔 묶음 | Button이라는 큰 묶음 |
| Variant | 묶음 안에 들어 있는 각각의 형태 | Primary / Medium / Default 버튼 하나 |
| Property | 무엇을 바꿀 수 있는지 나타내는 기준 | type, size, state |
| Value | Property가 가질 수 있는 선택값 | primary, md, disabled |
예를 들어 버튼 컴포넌트를 다음처럼 설계할 수 있습니다.
| Property | Value 예시 | 의미 |
|---|---|---|
type | primary, secondary, ghost | 버튼의 중요도와 시각적 스타일 |
size | sm, md, lg | 버튼의 크기 |
state | default, hover, pressed, disabled | 사용자의 조작에 따른 상태 |
이렇게 만들면 버튼을 사용할 때 매번 새로운 버튼을 복사해서 수정하지 않아도 됩니다. 인스턴스를 선택한 뒤 오른쪽 패널에서 type을 primary에서 secondary로 바꾸거나, state를 default에서 disabled로 바꾸면 됩니다.
중요한 점은 Variants가 단순히 모양을 바꾸는 기능이 아니라는 것입니다. Variants는 "우리 서비스에서 버튼은 어떤 종류가 있고, 어떤 상태를 가질 수 있는가?"를 정리하는 설계 도구입니다.
TIP · 용어가 헷갈릴 때
Property는 질문이고,Value는 답이라고 생각하면 쉽습니다.
"이 버튼의 크기는?"이라는 질문이size라면, "md입니다"라는 답이md입니다.
"이 버튼의 상태는?"이라는 질문이state라면, "disabled입니다"라는 답이disabled입니다.
버튼으로 Variant Set 만들기
가장 먼저 버튼을 예제로 Variant Set을 만들어 보겠습니다. 버튼은 Variants를 배우기에 가장 좋은 컴포넌트입니다. 크기, 색상, 상태, 아이콘 유무처럼 실무에서 필요한 조건이 한눈에 보이기 때문입니다.
먼저 기본 버튼 하나를 만듭니다. 텍스트 레이어를 만들고 로그인이라고 입력한 뒤, 텍스트를 감싸는 프레임을 만듭니다. 이 프레임에 Auto Layout을 적용합니다. 버튼은 내부 텍스트 길이에 따라 너비가 자연스럽게 늘어나야 하므로 Auto Layout과 궁합이 좋습니다.
버튼 프레임에는 좌우 패딩, 상하 패딩, 배경색, 모서리 둥글기 값을 지정합니다. 예를 들어 중간 크기의 Primary 버튼이라면 좌우 패딩은 16, 상하 패딩은 10, 모서리 둥글기는 8 정도로 시작할 수 있습니다. 값 자체가 정답은 아닙니다. 중요한 것은 같은 종류의 버튼이 같은 규칙을 따르도록 만드는 것입니다.
기본 버튼을 만들었다면 컴포넌트로 변환합니다. 그런 다음 복제해서 여러 상태를 만듭니다. 예를 들어 배경색이 조금 진한 버튼은 pressed, 투명도가 낮고 클릭할 수 없어 보이는 버튼은 disabled, 배경색이 살짝 밝아진 버튼은 hover로 정리할 수 있습니다.
이제 여러 컴포넌트를 선택하고 Combine as variants를 실행하면 하나의 Component Set으로 묶입니다. 피그마는 선택한 컴포넌트를 하나의 큰 점선 영역 안에 정리하고, 오른쪽 패널에서 속성을 관리할 수 있게 해 줍니다.
처음에는 피그마가 Property 1, Default, Variant2처럼 임시 이름을 붙일 수 있습니다. 이 이름을 그대로 두면 나중에 찾기 어렵습니다. 반드시 우리가 이해할 수 있는 이름으로 바꿔야 합니다.
예를 들어 버튼 Variant Set은 이렇게 정리할 수 있습니다.
| 컴포넌트 이름 | type | size | state |
|---|---|---|---|
| Button | primary | md | default |
| Button | primary | md | hover |
| Button | primary | md | pressed |
| Button | primary | md | disabled |
| Button | secondary | md | default |
| Button | secondary | md | hover |
| Button | secondary | md | pressed |
| Button | secondary | md | disabled |
이 표를 보면 처음에는 양이 많아 보일 수 있습니다. 하지만 실무에서는 이렇게 한 번 정리해 두는 편이 훨씬 안전합니다. 버튼이 화면마다 다르게 생기는 문제를 줄일 수 있고, 개발자와 이야기할 때도 "Primary 버튼의 Disabled 상태"처럼 정확하게 말할 수 있습니다.
단축키 박스 · 컴포넌트와 Variant 작업
Ctrl + Alt + K또는⌘ + Option + K: 선택한 레이어를 컴포넌트로 만들기Ctrl + D또는⌘ + D: 선택한 요소 복제하기
여러 컴포넌트 선택 후 오른쪽 클릭:Combine as variants실행하기Alt또는Option을 누른 채 드래그: 빠르게 복사하기
상태는 UI의 표정이다
상태를 잘 설계하려면 먼저 UI가 사용자에게 어떤 신호를 보내야 하는지 생각해야 합니다. 버튼이 아무 말 없이 가만히 있는 상태와, 마우스를 올렸을 때 반응하는 상태, 클릭했을 때 눌린 것처럼 보이는 상태, 사용할 수 없는 상태는 모두 다른 의미를 가집니다.
상태는 UI의 표정입니다. 같은 버튼이라도 지금 누를 수 있는지, 이미 선택되었는지, 문제가 생겼는지, 작업이 성공했는지를 상태로 표현합니다. 이 표정이 일관되지 않으면 사용자는 화면을 불안하게 느낍니다. 어떤 버튼은 회색이면 비활성이고, 어떤 버튼은 회색이어도 클릭된다면 사용자는 매번 추측해야 합니다.
실무에서 자주 쓰는 상태는 다음과 같습니다.
| 상태 | 의미 | 자주 쓰는 UI |
|---|---|---|
default | 기본 상태 | 버튼, 입력창, 탭, 체크박스 |
hover | 마우스를 올린 상태 | 데스크톱 버튼, 메뉴, 링크 |
pressed | 누르는 순간의 상태 | 버튼, 아이콘 버튼 |
focus | 키보드나 입력 커서가 활성화된 상태 | 입력창, 드롭다운, 버튼 |
disabled | 사용할 수 없는 상태 | 버튼, 입력창, 체크박스 |
error | 문제가 있는 상태 | 입력창, 폼, 알림 |
success | 완료 또는 성공 상태 | 입력창, 검증 메시지, 알림 |
selected | 선택된 상태 | 탭, 칩, 메뉴, 체크박스 |
모든 컴포넌트가 이 상태를 전부 가져야 하는 것은 아닙니다. 모바일 앱의 기본 화면에서는 hover가 필요 없을 수도 있습니다. 반대로 웹 관리자 페이지에서는 마우스 조작이 많기 때문에 hover, focus 상태가 중요합니다. 상태는 많을수록 좋은 것이 아니라, 실제 사용자 행동과 제품 환경에 맞게 충분해야 좋습니다.
특히 입력창은 상태 설계가 중요합니다. 사용자가 정보를 입력하는 과정에서 입력창은 계속 다른 신호를 보내야 합니다. 처음에는 비어 있는 기본 상태이고, 클릭하면 포커스 상태가 됩니다. 잘못 입력하면 에러 상태가 되고, 올바르게 입력하면 성공 상태로 바뀔 수 있습니다. 이 상태들이 제각각이면 폼 전체의 신뢰도가 떨어집니다.
예를 들어 이메일 입력창은 다음처럼 설계할 수 있습니다.
| state | 화면 표현 | 사용자에게 주는 메시지 |
|---|---|---|
default | 연한 회색 테두리, placeholder 표시 | 입력할 수 있음 |
focus | 브랜드 컬러 테두리, 커서 활성화 | 지금 입력 중임 |
error | 빨간 테두리, 에러 메시지 표시 | 입력값을 수정해야 함 |
success | 초록색 아이콘 또는 보조 메시지 | 입력값이 올바름 |
disabled | 흐린 배경, 낮은 대비 | 현재 수정할 수 없음 |
이렇게 상태를 정리하면 디자인뿐 아니라 기획 문서와 개발 구현도 쉬워집니다. 기획자는 "이메일 형식이 틀리면 error 상태를 보여 주세요"라고 말할 수 있고, 개발자는 그 상태에 해당하는 스타일을 찾아 구현할 수 있습니다.
이름 규칙이 곧 협업 규칙이다
Variants에서 가장 흔한 실수는 이름을 대충 붙이는 것입니다. 처음에는 혼자 작업하니 괜찮아 보입니다. 하지만 컴포넌트가 20개, 50개, 100개로 늘어나면 이름이 곧 시스템의 품질이 됩니다.
나쁜 이름은 이런 식입니다.
| 피해야 할 이름 | 문제가 되는 이유 |
|---|---|
버튼 파란거 | 색이 바뀌면 이름도 틀려짐 |
클릭전 | 어떤 상태인지 애매함 |
최종 disabled | 최종이라는 말은 시간이 지나면 의미가 없어짐 |
button_new_2 | 어디에 쓰는지 알기 어려움 |
좋은 이름은 역할과 상태를 예측할 수 있어야 합니다. 컴포넌트 이름은 사람이 읽기 쉬워야 하고, 속성값은 팀 안에서 반복해서 사용할 수 있어야 합니다.
버튼은 다음과 같은 규칙으로 시작하면 좋습니다.
| 항목 | 추천 이름 | 설명 |
|---|---|---|
| 컴포넌트 이름 | Button | UI 요소의 역할 |
| 종류 | type=primary | 중요도나 스타일 |
| 크기 | size=md | 크기 체계 |
| 상태 | state=default | 조작 또는 피드백 상태 |
| 아이콘 위치 | icon=none, left, right | 아이콘 표시 방식 |
입력창은 버튼과 조금 다르게 정리할 수 있습니다.
| 항목 | 추천 이름 | 설명 |
|---|---|---|
| 컴포넌트 이름 | Text Field | 입력 UI 역할 |
| 종류 | type=text, password, search | 입력 목적 |
| 상태 | state=default, focus, error | 입력 상황 |
| 보조 문구 | helper=true, false | 설명 문구 표시 여부 |
| 아이콘 | leadingIcon=true, false | 앞쪽 아이콘 여부 |
여기서 중요한 원칙은 "속성 이름은 기능을 설명하고, 값 이름은 선택지를 설명한다"는 것입니다. blue, red처럼 색상을 속성값으로 쓰는 것은 조심해야 합니다. 지금은 Primary 버튼이 파란색이어도, 브랜드 개편 후 보라색이 될 수 있습니다. 그런데 이름이 blue라면 실제 색과 이름이 어긋납니다. 그래서 색상보다 역할을 나타내는 primary, secondary, danger 같은 이름이 더 오래갑니다.
TIP · 이름 짓기 원칙
색상보다 역할을 먼저 이름에 담으세요.blue button보다primary button이 좋습니다.red button보다danger button이 좋습니다.
이름은 현재의 생김새가 아니라 앞으로도 유지될 역할을 기준으로 붙이는 편이 안전합니다.
Boolean 속성으로 켜고 끄기
Variants만으로 모든 경우의 수를 만들면 컴포넌트가 지나치게 많아질 수 있습니다. 예를 들어 버튼에 왼쪽 아이콘이 있는 경우와 없는 경우, 오른쪽 아이콘이 있는 경우와 없는 경우를 모두 Variant로 만들면 금방 수가 늘어납니다. 여기에 크기와 상태까지 곱해지면 관리하기 어려워집니다.
이럴 때 사용하는 것이 Boolean 속성입니다. Boolean은 참과 거짓, 즉 켜짐과 꺼짐을 뜻합니다. 피그마에서는 특정 레이어를 보이게 하거나 숨기는 옵션으로 활용할 수 있습니다.
예를 들어 버튼 안에 왼쪽 아이콘 레이어가 있다고 해 봅시다. 이 아이콘 레이어에 Boolean 속성을 연결하면 인스턴스를 사용할 때 오른쪽 패널에서 leadingIcon을 켜거나 끌 수 있습니다. 아이콘이 필요한 버튼에서는 켜고, 텍스트만 있는 버튼에서는 끄면 됩니다.
입력창에서도 Boolean 속성은 유용합니다. helperText를 켜면 아래 설명 문구가 보이고, 끄면 사라지게 만들 수 있습니다. clearButton을 켜면 검색창 오른쪽의 삭제 아이콘이 나타나고, 끄면 숨길 수 있습니다.
Boolean 속성을 쓸 만한 대표적인 경우는 다음과 같습니다.
| Boolean 속성 예시 | 켜졌을 때 | 꺼졌을 때 |
|---|---|---|
leadingIcon | 왼쪽 아이콘 표시 | 왼쪽 아이콘 숨김 |
trailingIcon | 오른쪽 아이콘 표시 | 오른쪽 아이콘 숨김 |
helperText | 보조 설명 표시 | 보조 설명 숨김 |
badge | 숫자 배지 표시 | 숫자 배지 숨김 |
divider | 구분선 표시 | 구분선 숨김 |
Boolean 속성을 잘 쓰면 Variant의 개수를 줄일 수 있습니다. 다만 모든 것을 Boolean으로 해결하려고 하면 오히려 복잡해집니다. 사용자 경험상 의미가 완전히 다른 상태라면 Variant로 분리하고, 단순히 보였다 사라지는 요소라면 Boolean으로 처리하는 편이 좋습니다.
Text 속성으로 라벨 바꾸기
버튼 컴포넌트를 인스턴스로 가져와 사용할 때 가장 자주 바꾸는 것은 텍스트입니다. 로그인, 가입하기, 저장, 삭제, 다음처럼 화면마다 버튼 라벨이 달라집니다.
예전 방식으로는 인스턴스 안의 텍스트 레이어를 직접 더블 클릭해서 바꾸곤 했습니다. 이 방식도 가능하지만 컴포넌트가 복잡해지면 텍스트 레이어를 찾기 번거롭습니다. Text 속성을 사용하면 오른쪽 패널에서 텍스트 값을 바로 바꿀 수 있습니다.
예를 들어 버튼 안의 텍스트 레이어에 label이라는 Text 속성을 연결해 둡니다. 그러면 인스턴스를 선택했을 때 오른쪽 패널에서 label 값을 로그인에서 계속하기로 바꿀 수 있습니다. 원본 컴포넌트의 구조는 그대로 유지하면서 화면에 맞는 문구만 바꾸는 것입니다.
입력창에서는 placeholder, value, helperText 같은 텍스트를 속성으로 만들 수 있습니다. 탭에서는 label을 속성으로 만들 수 있고, 배지에서는 count를 텍스트 속성으로 만들 수 있습니다.
Text 속성을 만들 때도 이름이 중요합니다. 버튼 문구는 label, 입력 전 안내 문구는 placeholder, 아래 설명은 helperText, 에러 문구는 errorMessage처럼 역할이 드러나게 붙이면 좋습니다.
TIP · Text 속성을 쓰면 좋은 상황
같은 구조를 유지한 채 문구만 자주 바뀌는 컴포넌트에 적합합니다.
버튼, 탭, 입력창, 배지, 메뉴 아이템처럼 라벨이 중요한 UI에서 특히 유용합니다.
인스턴스를 분해하지 않고도 문구를 바꿀 수 있어 원본 컴포넌트와의 연결이 안전하게 유지됩니다.
Instance Swap으로 아이콘 갈아 끼우기
이번에는 아이콘을 생각해 보겠습니다. 버튼 왼쪽에 화살표 아이콘이 들어갈 수도 있고, 다운로드 아이콘이 들어갈 수도 있습니다. 입력창 왼쪽에는 검색 아이콘이, 오른쪽에는 눈 모양 아이콘이나 삭제 아이콘이 들어갈 수 있습니다.
아이콘마다 Variant를 따로 만들면 수가 너무 많아집니다. 이때 사용하는 기능이 Instance Swap 속성입니다. Instance Swap은 컴포넌트 안에 들어 있는 하위 인스턴스를 다른 컴포넌트로 바꿔 끼울 수 있게 해 줍니다.
예를 들어 버튼 안에 Icon / Arrow Right 인스턴스를 넣어 두고, 이 아이콘 레이어에 icon이라는 Instance Swap 속성을 연결합니다. 그러면 버튼 인스턴스를 사용할 때 오른쪽 패널에서 아이콘을 Arrow Right, Download, Plus, Check 등으로 바꿀 수 있습니다.
Instance Swap이 특히 강력한 이유는 구조를 유지하면서 내용만 교체할 수 있기 때문입니다. 버튼의 패딩, 간격, 상태, 크기 규칙은 그대로 두고 아이콘만 바뀝니다. Auto Layout이 적용되어 있다면 아이콘이 바뀌어도 텍스트와의 간격이 일정하게 유지됩니다.
다만 Instance Swap을 편하게 쓰려면 아이콘 컴포넌트도 미리 정리되어 있어야 합니다. 아이콘 이름이 제각각이면 선택 목록에서 찾기 어렵습니다. Icon / Search, Icon / Plus, Icon / Check, Icon / Arrow Right처럼 같은 규칙으로 이름을 붙여 두면 훨씬 빠르게 찾을 수 있습니다.
입력창 Variant Set 설계하기
이제 버튼보다 조금 더 복잡한 입력창을 설계해 보겠습니다. 입력창은 상태가 많고, 보조 문구와 아이콘이 함께 붙는 경우가 많아서 Variants와 Component Properties를 함께 연습하기 좋습니다.
입력창의 기본 구조는 보통 라벨, 입력 영역, 보조 문구로 나뉩니다. 입력 영역 안에는 placeholder나 입력값이 들어가고, 필요하면 왼쪽 아이콘이나 오른쪽 아이콘이 붙습니다. 에러 상태에서는 테두리 색이 바뀌고, 아래에 에러 메시지가 나타날 수 있습니다.
입력창을 만들 때는 먼저 세로 Auto Layout 프레임을 만듭니다. 그 안에 라벨 텍스트, 입력 박스 프레임, 보조 문구 텍스트를 차례로 넣습니다. 입력 박스 프레임에는 다시 가로 Auto Layout을 적용해 아이콘, 텍스트, 오른쪽 아이콘이 자연스럽게 배치되도록 합니다.
그다음 상태를 나눕니다. 처음부터 모든 상태를 만들기보다 실무에서 꼭 필요한 상태부터 시작하는 것이 좋습니다. 예를 들어 기본 입력창이라면 default, focus, error, disabled 네 가지면 충분할 수 있습니다. 이메일 인증이나 결제 정보처럼 검증이 중요한 화면에서는 success 상태를 추가할 수 있습니다.
입력창 Variant Set은 다음처럼 구성할 수 있습니다.
| Component | type | state | 설명 |
|---|---|---|---|
| Text Field | text | default | 기본 입력 가능 상태 |
| Text Field | text | focus | 현재 입력 중인 상태 |
| Text Field | text | error | 입력값에 문제가 있는 상태 |
| Text Field | text | success | 입력값이 확인된 상태 |
| Text Field | text | disabled | 입력하거나 수정할 수 없는 상태 |
여기에 Boolean과 Text 속성을 더하면 훨씬 유연해집니다. label은 Text 속성으로, placeholder도 Text 속성으로 만듭니다. helperText는 보이거나 숨길 수 있도록 Boolean 속성으로 연결합니다. 왼쪽 아이콘은 leadingIcon Boolean으로 표시 여부를 제어하고, 어떤 아이콘을 쓸지는 Instance Swap으로 바꾸게 만들 수 있습니다.
이렇게 만들면 하나의 입력창 컴포넌트로 다양한 상황을 처리할 수 있습니다. 로그인 화면에서는 이메일 입력창으로 쓰고, 검색 화면에서는 검색어를 입력하세요라는 placeholder와 검색 아이콘을 넣어 쓸 수 있습니다. 회원가입 화면에서는 에러 메시지를 켜고 올바른 이메일 형식이 아닙니다라는 문구를 넣을 수도 있습니다.
탭과 체크박스의 상태 설계
버튼과 입력창을 이해했다면 탭과 체크박스도 같은 방식으로 볼 수 있습니다. 탭은 여러 선택지 중 현재 선택된 항목을 보여 주는 UI입니다. 그래서 가장 중요한 상태는 selected입니다. 여기에 마우스를 올렸을 때의 hover, 사용할 수 없는 disabled를 추가할 수 있습니다.
탭은 보통 다음처럼 설계합니다.
| Component | state | 의미 |
|---|---|---|
| Tab Item | default | 선택되지 않은 기본 상태 |
| Tab Item | hover | 마우스를 올린 상태 |
| Tab Item | selected | 현재 선택된 상태 |
| Tab Item | disabled | 선택할 수 없는 상태 |
탭에서 흔히 하는 실수는 선택된 탭을 단순히 색만 다르게 만드는 것입니다. 색상 차이도 중요하지만, 밑줄이나 배경, 글자 두께처럼 다른 신호를 함께 주면 더 명확합니다. 특히 접근성을 생각하면 색상 하나에만 의존하지 않는 편이 좋습니다.
체크박스는 조금 다른 방식으로 설계할 수 있습니다. 체크박스에는 선택 여부가 중요하므로 checked라는 Boolean 성격의 속성이 잘 어울립니다. 여기에 state를 더해 기본, 호버, 비활성 상태를 구분할 수 있습니다.
예를 들면 다음과 같습니다.
| Component | checked | state | 의미 |
|---|---|---|---|
| Checkbox | false | default | 선택되지 않은 기본 상태 |
| Checkbox | true | default | 선택된 기본 상태 |
| Checkbox | false | hover | 선택되지 않은 상태에서 마우스 오버 |
| Checkbox | true | hover | 선택된 상태에서 마우스 오버 |
| Checkbox | false | disabled | 선택할 수 없는 미선택 상태 |
| Checkbox | true | disabled | 선택되어 있지만 변경할 수 없는 상태 |
이런 표를 먼저 그려 보면 실제로 어떤 Variant가 필요한지 보입니다. 무작정 컴포넌트를 복제하기 전에, 상태표를 만드는 습관을 들이면 디자인 시스템의 품질이 크게 좋아집니다.
Variant가 너무 많아질 때 정리하는 법
Variants를 배우고 나면 모든 경우의 수를 Variant로 만들고 싶어집니다. 하지만 조심해야 합니다. type이 4개, size가 3개, state가 5개, icon이 3개라면 단순 계산으로 180개 조합이 생깁니다. 실제로 이 조합을 모두 만들면 관리가 거의 불가능해집니다.
그래서 Variants를 설계할 때는 "무엇을 Variant로 만들고, 무엇을 속성으로 처리할지"를 판단해야 합니다.
| 상황 | 추천 방식 | 이유 |
|---|---|---|
| 시각적 규칙이 크게 달라짐 | Variant | 상태나 종류로 구분하는 편이 명확함 |
| 단순히 보이고 숨겨짐 | Boolean 속성 | Variant 수를 줄일 수 있음 |
| 문구만 바뀜 | Text 속성 | 구조를 유지한 채 텍스트만 변경 가능 |
| 아이콘 종류만 바뀜 | Instance Swap 속성 | 아이콘 컴포넌트를 갈아 끼우면 됨 |
| 실제로 거의 쓰지 않는 조합 | 만들지 않음 | 불필요한 관리 비용을 줄임 |
예를 들어 버튼의 state는 Variant로 만드는 편이 좋습니다. default와 disabled는 색, 투명도, 커서 의미, 클릭 가능 여부가 다르기 때문입니다. 반면 버튼 왼쪽 아이콘의 표시 여부는 Boolean 속성으로 처리해도 충분합니다. 버튼 라벨은 Text 속성으로 바꾸는 편이 더 좋습니다.
이 판단이 익숙해지면 컴포넌트가 훨씬 가벼워집니다. 모든 경우의 수를 만드는 것이 아니라, 자주 쓰는 핵심 구조만 단단하게 만들고 나머지는 속성으로 조절하는 것입니다.
실무 팁 박스 · Variant 폭발을 막는 기준
상태와 종류처럼 의미가 달라지는 것은 Variant로 분리합니다.
아이콘, 보조 문구, 배지처럼 켜고 끄는 요소는 Boolean을 먼저 검토합니다.
라벨과 안내 문구처럼 내용만 달라지는 것은 Text 속성으로 처리합니다.
아이콘 종류처럼 들어갈 컴포넌트만 바뀌는 것은 Instance Swap을 사용합니다.
실제 화면에서 쓰지 않는 조합은 과감히 만들지 않습니다.
Assets 패널에서 잘 찾히는 컴포넌트 만들기
컴포넌트는 잘 만드는 것만큼 잘 찾는 것도 중요합니다. 아무리 훌륭한 버튼 Variant Set을 만들어도 팀원이 Assets 패널에서 찾지 못하면 다시 새로 그리게 됩니다.
피그마의 Assets 패널에서는 컴포넌트 이름을 기준으로 검색하고 삽입할 수 있습니다. 따라서 이름 구조가 검색 친화적이어야 합니다. 예를 들어 Button, Text Field, Checkbox, Tab Item처럼 UI 역할이 앞에 드러나는 이름이 좋습니다.
컴포넌트를 종류별로 묶어 보이게 하고 싶다면 슬래시(/)를 활용할 수 있습니다. 예를 들어 Button/Primary처럼 이름을 붙이면 Assets 패널에서 계층처럼 정리되어 보입니다. 다만 Variants를 사용하는 경우에는 모든 조합을 이름에 길게 쓰기보다, Component Set 이름은 Button으로 두고 세부 차이는 Property로 관리하는 편이 더 깔끔합니다.
아이콘은 검색성이 특히 중요합니다. 아이콘 이름이 Vector 32, icon_new, search2처럼 되어 있으면 Instance Swap 목록에서 찾기 어렵습니다. 처음부터 Icon / Search, Icon / Close, Icon / Check, Icon / Plus처럼 정리해 두면 버튼이나 입력창에서 아이콘을 교체할 때 시간이 크게 줄어듭니다.
TIP · Assets 패널 검색을 위한 이름 규칙
컴포넌트의 역할이 이름 앞에 오게 합니다. 예:Button,Text Field,Checkbox
아이콘은Icon / 이름형식으로 통일합니다. 예:Icon / Search
상태 이름은 Property로 관리합니다. 예:state=disablednew,copy,final같은 임시 단어는 컴포넌트 이름에 남기지 않습니다.
기획자와 개발자에게도 좋은 상태 설계
Variants는 디자이너만 편하게 해 주는 기능이 아닙니다. 상태가 잘 정리된 디자인 파일은 기획자와 개발자에게도 큰 도움이 됩니다.
기획자는 화면 정책을 더 명확하게 쓸 수 있습니다. "필수값을 입력하지 않으면 저장 버튼은 disabled 상태가 된다", "비밀번호가 조건에 맞지 않으면 입력창은 error 상태가 된다", "인증이 완료되면 success 상태와 완료 메시지를 보여 준다"처럼 상태를 기준으로 정책을 정리할 수 있습니다.
개발자는 구현 기준을 더 쉽게 파악할 수 있습니다. 버튼의 기본, 호버, 눌림, 비활성 스타일이 한곳에 모여 있으면 CSS나 컴포넌트 코드로 옮기기 쉽습니다. React, Vue 같은 프런트엔드 환경에서도 type, size, state, disabled, label, icon 같은 속성은 실제 코드의 props와 비슷한 역할을 합니다. 피그마의 Property 이름을 개발 코드와 비슷하게 맞추면 협업이 더 자연스러워집니다.
예를 들어 디자인에서는 type=primary, size=md, state=disabled로 정리하고, 개발에서는 <Button type="primary" size="md" disabled>처럼 구현할 수 있습니다. 완전히 같은 이름을 써야 하는 것은 아니지만, 개념이 맞아떨어지면 의사소통 비용이 줄어듭니다.
디자인 시스템은 거창한 문서에서 시작하지 않습니다. "버튼의 상태를 어떻게 부를 것인가", "입력창의 에러 상태는 어떻게 생겼는가", "체크박스의 선택 상태는 어떻게 표현할 것인가"를 정리하는 순간 이미 디자인 시스템이 시작됩니다.
실수하기 쉬운 지점
Variants를 처음 만들 때 가장 많이 하는 실수는 상태를 눈에 보이는 색 차이로만 이해하는 것입니다. 하지만 상태는 단순한 색상 변경이 아닙니다. 클릭 가능한지, 입력 중인지, 오류가 있는지, 선택되었는지를 사용자에게 알려 주는 약속입니다.
또 다른 실수는 원본 컴포넌트 내부 구조가 Variant마다 달라지는 것입니다. 어떤 버튼은 텍스트 레이어 이름이 Label이고, 어떤 버튼은 Text이며, 어떤 버튼은 아이콘이 Auto Layout 밖에 있으면 나중에 수정하기 어렵습니다. Variant들은 가능한 한 같은 레이어 구조를 유지하는 것이 좋습니다. 그래야 Text 속성, Boolean 속성, Instance Swap 속성을 안정적으로 사용할 수 있습니다.
세 번째 실수는 너무 일찍 복잡한 시스템을 만들려는 것입니다. 처음부터 모든 버튼 크기, 모든 색상, 모든 상태를 완벽하게 만들 필요는 없습니다. 현재 프로젝트에서 실제로 쓰는 것부터 만들고, 반복해서 등장하는 패턴이 보일 때 확장하면 됩니다.
실무에서는 완벽한 첫 설계보다 고치기 쉬운 구조가 더 중요합니다. 이름이 명확하고, 속성이 정리되어 있고, 불필요한 조합이 적다면 나중에 얼마든지 확장할 수 있습니다.
작은 디자인 시스템 만들기
이제 우리는 Component에서 한 단계 더 나아왔습니다. 단순히 버튼을 재사용하는 수준이 아니라, 버튼이 가질 수 있는 종류와 상태를 체계로 만들기 시작했습니다. 이것이 디자인 시스템의 출발점입니다.
디자인 시스템이라고 하면 대기업에서 만드는 거대한 라이브러리를 떠올리기 쉽습니다. 하지만 작은 프로젝트에서도 디자인 시스템은 필요합니다. 로그인 버튼 하나, 이메일 입력창 하나, 체크박스 하나를 일관되게 관리하는 것만으로도 화면의 완성도가 달라집니다.
처음에는 다음 네 가지 컴포넌트만 정리해도 충분합니다.
| 컴포넌트 | 먼저 만들 상태 | 추가하면 좋은 속성 |
|---|---|---|
| Button | default, hover, pressed, disabled | type, size, label, icon |
| Text Field | default, focus, error, disabled | label, placeholder, helperText, icon |
| Tab Item | default, hover, selected, disabled | label, badge |
| Checkbox | checked, unchecked, disabled | label, helperText |
이 네 가지는 대부분의 화면에서 반복해서 등장합니다. 여기에 Auto Layout이 잘 적용되어 있고, Components와 Variants가 안정적으로 연결되어 있다면 작은 서비스 화면을 만드는 데 필요한 기본 뼈대가 갖춰집니다.
핵심 요약
Variants는 같은 역할을 하는 컴포넌트의 여러 형태를 하나의 Component Set으로 묶어 관리하는 기능입니다. 버튼의 type, size, state처럼 바꿀 수 있는 기준을 Property라고 하고, primary, md, disabled처럼 실제 선택값을 Value라고 합니다.
상태 설계는 UI가 사용자에게 보내는 신호를 정리하는 일입니다. default, hover, pressed, focus, disabled, error, success, selected 같은 상태를 일관되게 정의하면 디자이너, 기획자, 개발자가 같은 언어로 소통할 수 있습니다.
Variant가 너무 많아지지 않도록 Component Properties를 함께 사용해야 합니다. 단순히 보이고 숨겨지는 요소는 Boolean 속성으로, 자주 바뀌는 문구는 Text 속성으로, 아이콘처럼 교체되는 하위 컴포넌트는 Instance Swap 속성으로 처리하면 관리가 쉬워집니다.
이름 규칙은 디자인 시스템의 기본 질서입니다. 색상보다 역할을 기준으로 primary, secondary, danger처럼 이름을 붙이고, 상태는 state=default, state=disabled처럼 예측 가능한 방식으로 정리하는 것이 좋습니다.
실습 과제
이번 실습에서는 상태가 있는 버튼과 입력창 Variant Set을 직접 만들어 봅니다. 목표는 예쁜 화면을 완성하는 것이 아니라, 상태와 속성을 체계적으로 관리하는 감각을 익히는 것입니다.
과제 1. 버튼 Variant Set 만들기
새 페이지나 Components 섹션에 버튼 기본형을 만드세요. 버튼에는 Auto Layout을 적용하고, 텍스트 레이어 이름은 Label로 정리합니다. 기본 버튼을 컴포넌트로 만든 뒤 Variant Set으로 묶습니다.
다음 조건을 만족하도록 구성해 보세요.
| Property | Value |
|---|---|
type | primary, secondary |
size | sm, md, lg |
state | default, hover, pressed, disabled |
모든 조합을 다 만들기 어렵다면 먼저 type=primary, size=md 기준으로 네 가지 상태를 만들고, 그다음 secondary와 다른 크기로 확장해도 됩니다. 버튼 라벨은 Text 속성 label로 연결하고, 왼쪽 아이콘 표시 여부는 Boolean 속성 leadingIcon으로 만들어 보세요.
과제 2. 입력창 Variant Set 만들기
이메일 입력창을 만든다고 가정합니다. 세로 Auto Layout 프레임 안에 라벨, 입력 박스, 보조 문구를 배치합니다. 입력 박스 안에는 placeholder 텍스트와 필요하다면 아이콘을 넣습니다.
다음 상태를 Variant로 만들어 보세요.
| state | 표현 조건 |
|---|---|
default | 기본 회색 테두리와 placeholder 표시 |
focus | 브랜드 컬러 테두리 표시 |
error | 빨간 테두리와 에러 메시지 표시 |
success | 성공을 나타내는 색상 또는 아이콘 표시 |
disabled | 흐린 배경과 낮은 대비 적용 |
추가로 label, placeholder, helperText를 Text 속성으로 연결해 보세요. 보조 문구를 보이거나 숨길 수 있도록 Boolean 속성도 만들어 봅니다.
과제 3. 상태표 먼저 작성하기
피그마에서 바로 그리기 전에, 아래 형식으로 상태표를 먼저 작성해 보세요. 이 표는 기획자와 개발자에게도 공유할 수 있는 좋은 기준이 됩니다.
| UI 요소 | 필요한 상태 | 상태별 차이 | 비고 |
|---|---|---|---|
| Button | default, hover, pressed, disabled | 배경색, 글자색, 투명도 | Primary 기준 |
| Text Field | default, focus, error, success, disabled | 테두리, 메시지, 아이콘 | 이메일 입력 기준 |
| Checkbox | unchecked, checked, disabled | 체크 표시, 배경, 라벨 색 | 약관 동의 기준 |
실습을 마쳤다면 실제 화면에 버튼과 입력창 인스턴스를 배치해 보세요. 오른쪽 패널에서 Property를 바꿨을 때 원하는 상태로 자연스럽게 전환된다면 성공입니다.
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.
