바이브코딩을 하다 UI를 손볼 때마다 “이게 아닌데…” 를 반복하면서 수정이 끝없이 늘었다. 원인은 명확했다. 내가 원하는 모습을 정확한 어휘로 묘사하지 못해서다.
“버튼 예쁘게 해줘”, “화면 부드럽게 넘어가게” 같은 말로 시키면 AI는 자기가 해석한 ‘예쁨’ 과 ‘부드러움’ 을 만들어준다. 운이 좋으면 한 번에 맞지만, 대부분 두세 차례 핑퐁이 더 필요하다. 그러느니 처음부터 정확한 어휘로 지시하는 게 빠르다.
그래서 시작한 용어 정리 시리즈의 첫 글. UI 편.
📍 본문에 나오는 UI 요소들은 글 마지막 링크에서 직접 만져볼 수 있게 따로 페이지를 만들어뒀다.
Table of contents
Open Table of contents
UI를 말로 시키는 두 가지 도구
깊이 파보니 결국 두 가지로 압축된다.
- 묘사하는 어휘 — 상태 / 시간 / 가속 같은 개념어로 UI를 정확히 묘사
- 레퍼런스 주는 습관 — 비슷한 다른 서비스의 UI를 기준점으로 제시
이 글은 1번에 집중한다. 그 어휘는 다시 네 영역으로 나뉜다.
| 영역 | 핵심 어휘 | 깊이 필요? |
|---|---|---|
| 구성요소 & 상태 | 버튼·입력창·카드·모달 / default·hover·active·disabled·loading·focus | 🔴 깊게 |
| 움직임 | property·duration·easing | 🔴 깊게 |
| 모양 | 위계·typography·색·여백 | 🟡 보통 (AI 결과 보고 고치는 게 빠름) |
| 글 | 버튼 문구·에러 메시지·빈 화면 | 🟢 어휘보다 직접 정해주는 게 빠름 |
가장 깊게 파야 하는 건 구성요소&상태 와 움직임.
1장. 구성요소와 상태 — 모양보다 “상태”로 접근하라
UI에는 많은 컴포넌트가 있다. 그 중에서 버튼은 모든 컴포넌트의 축소판이다. 버튼 프롬프트를 제대로 쓸 줄 알면 나머지는 같은 사고의 응용.
완성도 있는 버튼을 만들려면 “모양”이 아니라 “상태”에 집중해야 한다.
버튼의 다섯 가지 상태
| 상태 | 이름 | 언제 | 시각적 단서 |
|---|---|---|---|
| 평상시 | default | 아무 일 없을 때 | 기본 모양 |
| 마우스 올림 | hover | 커서를 올렸을 때 | 살짝 어두워지거나 색이 변함 |
| 누름 | active (pressed) | 누르는 순간 | 눌린 느낌 (살짝 작아지거나 더 어두워짐) |
| 비활성화 | disabled | 누를 수 없을 때 | 흐릿하게, 커서도 막기 |
| 로딩 | loading | 요청 처리 중 | 스피너 + 잠금 |
특히 hover 와 loading 의 유무가 “완성된 버튼” 과 “밋밋한 버튼” 을 가른다.
지시문 비교
- ❌ “로그인 버튼 만들어줘.”
- ✅ “로그인 버튼 만들어줘. hover 하면 살짝 어두워지고, 누르면 살짝 작아지면서 눌린 느낌이 나고, 로그인 요청 중에는 버튼 안에 스피너가 돌면서 disabled 되게 해줘.”
다른 컴포넌트도 똑같이 “상태”로 접근
- input (입력창): default / focus(클릭해서 입력중 — 보통 테두리 강조) / error(빨간 테두리 + 메시지) / filled(채워짐) / disabled
- card: default / hover(살짝 떠오르거나 테두리 강조) / selected
- modal: 가운데 뜨는 팝업. 나타날 때 / 사라질 때 의 전환이 핵심 (→ 2장)
- toast: 잠깐 떴다 사라지는 알림. “3초 뒤 자동으로 사라져라” 식으로 시간을 같이 준다
- tooltip: 마우스 올리면 뜨는 작은 설명
2장. 움직임 — 세 가지 선택
움직임을 가르는 정체는 사실 세 가지 선택으로 압축된다.
첫째 — 무엇이 움직이나 (property)
| property | 효과 |
|---|---|
opacity (투명도) | 0→1 로 변하면 서서히 나타나고, 반대면 사라진다 |
transform: translate (위치) | 위치가 변하면 슬라이드된다 |
scale (크기) | 작게→크게 변하면 팝업처럼 커진다 |
보통 둘을 섞는다. “투명도 + 위치” 를 합치면 흔히 보는 “아래에서 떠오르며 나타나는” 효과가 된다.
둘째 — 얼마나 오래 (duration)
| 시간 | 느낌 | 어디에 쓰나 |
|---|---|---|
| 0.15 ~ 0.2초 | 즉각적 | 버튼 반응, 작은 인터랙션 |
| 0.3초 안팎 | 자연스러움 | 화면 전환의 기본값 |
| 0.5초 이상 | 느긋, 우아 | 의도적으로 천천히 보여줄 때 |
셋째 — 어떤 가속 (easing / timing function)
| easing | 곡선 | 어디에 쓰나 |
|---|---|---|
linear (등속) | 일정 속도, 기계적 | 거의 안 씀 |
ease-in (느리게 시작) | 천천히 출발 | 사라지는 요소 |
ease-out (느리게 끝) | 천천히 도착 | 등장하는 요소에 가장 자연스러움 |
ease-in-out (양끝 느리게) | 부드러운 이동 | 위치 이동 |
bounce / overshoot (튕김) | 끝에서 살짝 튕김 | 장난스럽고 통통 튀는 느낌 |
지시문 비교
- ❌ “카드 부드럽게 나타나게”
- ✅ “카드가 아래에서 위로 슬쩍 올라오면서, 0.3초 동안, 천천히 끝나는 가속(ease-out) 으로 나타나게”
3장. 모양 — 핵심은 “위계(hierarchy)”
모양 파트에서 가장 중요한 건 위계 다. “이 화면에서 뭐가 제일 중요한가” 를 알려주는 것.
- 버튼 위계: 가장 중요한 버튼은 꽉 찬 색(primary), 덜 중요한 건 테두리만(secondary / ghost), 위험한 동작은 빨강(danger)
- 타이포그래피: 크기(
font-size), 굵기(font-weight), 줄 간격(line-height) - 색: 주색 하나 + 의미색(success / warning / danger) 정도면 충분
- 여백·정렬: 균일한 간격, 정렬 기준선
이 칸은 미리 외우기보다 AI 결과를 보고 그때그때 고쳐나가는 게 더 빠르다.
4장. 글 — 작은 영역이지만 인상이 갈린다
이 부분도 사실 UI다. 버튼에 “확인” 이라고 쓸지 “기록” 이라고 쓸지, 에러를 “오류 발생” 이라고 할지 “메일 형식을 확인해주세요” 라고 할지.
AI는 기본적으로 어색한 문구를 넣기 때문에 내가 직접 문구를 정해주는 게 빠르다.
- 버튼 문구: 동작이 분명한 동사로 (“저장” 보다는 “기록 저장”)
- 에러 메시지: 무엇이 잘못됐고 어떻게 고칠지 — 비난조 아닌 안내조로
- 빈 화면: 데이터가 없을 때 행동을 유도하는 한 줄
직접 만져보는 playground
🎮 UI 용어 playground — 위에서 다룬 버튼 상태 / 애니메이션 / easing / 컴포넌트 전환을 직접 호버·클릭하면서 볼 수 있게 만들어뒀다.
글로만 본 개념을 눈과 손으로 확인 하면 어휘가 훨씬 빠르게 자기 것이 된다. 다음에 AI에게 지시할 때 그 감각이 도움이 될 거다.
더 공부해볼 것
1. Tailwind CSS / Material Design / Apple HIG 의 어휘
- Tailwind는 위 어휘를 다 클래스로 가지고 있음 (
hover:,active:,disabled:,transition-,ease-out…) - Material Design 의 elevation·motion 가이드
- Apple Human Interface Guidelines 의 transition 권장값
- 어느 디자인 시스템이든 같은 개념어를 쓰고 있다는 걸 확인하기 좋음
2. CSS Animation / Web Animations API 본격 학습
@keyframes와transition의 차이 / 언제 어떤 걸 쓰나- JS의
Element.animate()와requestAnimationFrame - 60fps를 깨지 않으려면 무엇을 animate 해야 하는가 (transform / opacity 가 GPU 가속, layout 속성은 무거움)
3. Easing 곡선의 수학
cubic-bezier(x1, y1, x2, y2)직접 정의하기- cubic-bezier.com 같은 도구로 감 잡기
- spring 물리 기반 애니메이션 (Framer Motion 등)
4. 디자인 시스템·컴포넌트 라이브러리 조사
- Shadcn UI, Radix UI, Headless UI — 상태 관리 패턴 학습용
- 컴포넌트 하나의 props로 다섯 가지 상태를 어떻게 표현하는지 코드 읽어보기
5. 다음 용어 정리 시리즈
- 데이터베이스 용어 (정규화·인덱스·트랜잭션·격리 수준)
- 인증·인가 (OAuth·OIDC·JWT — 어제 카카오 로그인 글이 시작점)
- 백엔드 아키텍처 (REST·gRPC·이벤트 드리븐)
- 시리즈가 쌓이면 본인 표준 어휘집이 된다
회고
바이브코딩에서 내 역할은 타이핑하는 사람이 아니라 판단하는 사람이다. AI가 빠르게 코드를 뽑아내는 시대에 내가 해야 할 일은 정확히 시키고, 정확히 판단하는 것. 그러기 위한 도구가 어휘.
이번에 정리하면서 다시 확인한 것: 개념을 외운다고 잘 시키는 게 아니라, 실제로 만져본 경험과 어휘가 연결됐을 때 비로소 자연스럽게 입에서 나온다. 그래서 playground를 같이 만들었다. 앞으로 새 용어를 만날 때마다 본문 + 체험 페이지 같이 만드는 패턴으로 시리즈를 이어갈 예정.