← 전체 카테고리
06

인터랙션 & 상태

시안에서 가장 많이 빠지는 것이 상태입니다. 기본 모양만 그려서 넘기면 나머지는 개발자가 임의로 만듭니다. 그리고 모바일에는 호버가 없습니다.

19개 용어19개 라이브 데모
상태는 6개 세트로 생각하세요

기본 · 호버 · 포커스 · 눌림 · 선택됨 · 비활성. 컴포넌트 하나를 만들 때마다 이 6가지를 정의해두면 개발이 헤매지 않습니다 → 깊게 보기: 버튼 하나에 상태가 6개나 필요한 이유

01

상태

State

이런 상황에서 나옵니다

개발자가 "호버는 어떻게 되나요?"라고 물을 때. 시안에 없으면 여기서 막힙니다.

요소가 처해 있는 조건입니다. 같은 버튼이라도 평소·마우스 올렸을 때·눌렀을 때·비활성일 때 모양이 달라야 합니다.

눈으로 보기 직접 눌러보세요
기본
호버
포커스
눌림
선택됨
비활성

이 6개 세트를 컴포넌트마다 정의하는 것이 디자인 시스템의 시작입니다. → 깊게 보기에서 단계별로

헷갈리는 지점

디자인 시안에서 가장 많이 빠지는 게 상태입니다. 기본만 그려서 주면 나머지는 개발자가 알아서 만듭니다. 최소한 기본·호버·포커스·활성·비활성·로딩 6가지는 정의해서 넘기세요.

이렇게 요청하세요

컴포넌트마다 상태를 6종 정의해주세요 — 기본 / 호버 / 포커스 / 눌림 / 선택됨 / 비활성. 데이터를 기다리는 로딩 상태도 함께 넣어주세요.

02

호버

Hover

이런 상황에서 나옵니다

"마우스 올리면 색 바뀌게 해주세요" — 그리고 모바일 얘기가 반드시 뒤따라야 합니다.

마우스 커서를 요소 위에 올려둔 상태입니다. 클릭하기 전에 "여기 누를 수 있어요"를 알려줍니다.

눈으로 보기 직접 눌러보세요
숨은 설명

모바일 기기로 보고 있다면 아무 변화가 없을 겁니다. 그것이 바로 문제의 핵심입니다.

헷갈리는 지점

모바일에는 호버가 없습니다. 손가락은 화면에 닿거나 안 닿거나 둘 중 하나입니다. 그래서 호버로만 보여주는 정보는 모바일에서 영영 볼 수 없습니다. 드롭다운 메뉴를 호버로만 열면 모바일에서 안 열립니다 — 실무에서 정말 자주 나오는 사고입니다.

이렇게 요청하세요

호버 효과를 넣되, 호버로만 접근 가능한 기능은 만들지 말아주세요. 모바일에는 호버가 없으니 클릭(탭)으로도 반드시 동작해야 합니다.

03

포커스

Focus

이런 상황에서 나옵니다

"이 파란 테두리 지워주세요" — 말려야 하는 요청입니다.

키보드 Tab 키로 선택된 상태입니다. 지금 어느 요소를 조작하고 있는지 알려줍니다.

눈으로 보기 직접 눌러보세요

클릭하지 말고 Tab 키만 눌러 이동해보세요. 지금 어디에 있는지 보이는 게 정상입니다.

헷갈리는 지점

포커스 테두리가 못생겼다고 지우면 절대 안 됩니다. 마우스를 못 쓰는 사용자는 그 순간 화면에서 길을 잃습니다. 디자인이 마음에 안 들면 지우지 말고 더 예쁜 포커스 스타일을 그려서 주세요.

이렇게 요청하세요

포커스 링을 지우지 말아주세요. 대신 브랜드 색으로 스타일만 바꿔주세요. 마우스 클릭 시에는 안 보이고 키보드 이동 시에만 보이게 하려면 :focus-visible을 써주세요.

04

액티브 · 프레스드

Active · Pressed

이런 상황에서 나옵니다

"버튼 눌러도 반응이 없어요" — 중복 주문 사고의 원인.

버튼을 누르고 있는 그 순간의 상태입니다. 손가락을 떼면 사라집니다.

눈으로 보기 직접 눌러보세요
← 누르는 동안 살짝 내려갑니다
헷갈리는 지점

모바일에서 이 반응이 없으면 사용자는 "안 눌렸나?" 하고 여러 번 누릅니다. 그러면 주문이 중복되기도 합니다. 눌림 반응은 장식이 아니라 오작동 방지 장치입니다.

이렇게 요청하세요

버튼에 눌림(active) 상태를 넣어주세요. 그리고 제출 버튼은 한 번 누르면 비활성+로딩으로 바꿔서 중복 클릭을 막아주세요.

05

셀렉티드

Selected

이런 상황에서 나옵니다

"지금 어떤 필터가 켜져 있는지 모르겠어요"

선택되어 계속 유지되는 상태입니다. 손을 떼도 그대로 남습니다.

눈으로 보기 직접 눌러보세요
헷갈리는 지점

액티브(누르는 순간)와 다릅니다. 탭·필터 칩·체크박스는 셀렉티드가 있어야 지금 무엇이 켜져 있는지 알 수 있습니다. 선택 상태를 색깔로만 표시하면 색약 사용자가 구분 못 하므로 굵기·아이콘도 함께 바꿔주세요.

이렇게 요청하세요

선택된 상태를 색뿐 아니라 글자 굵기와 체크 아이콘으로도 구분해주세요. 색약 사용자도 알아볼 수 있어야 합니다.

06

디스에이블드

Disabled · 비활성

이런 상황에서 나옵니다

"왜 버튼이 안 눌리죠?" — 사용자 문의로 돌아오는 상태.

지금은 쓸 수 없는 상태입니다. 흐리게 처리되고 눌러도 반응하지 않습니다.

눈으로 보기 직접 눌러보세요
✗ 이유를 안 알려줌
✓ 이유를 함께 표시
약관에 동의하면 가입할 수 있습니다
헷갈리는 지점

왜 비활성인지 알려주지 않으면 사용자는 그냥 막힙니다. "약관에 동의해야 가입할 수 있습니다" 같은 설명을 옆에 두거나, 아예 버튼을 활성화해두고 누르면 부족한 항목을 알려주는 방식이 더 나은 경우가 많습니다.

이렇게 요청하세요

비활성 버튼 아래에 왜 비활성인지 안내 문구를 넣어주세요. 또는 버튼을 활성으로 두고 누르면 부족한 항목으로 스크롤·포커스 이동하는 방식도 검토해주세요.

07

리드온리

Read-only · 읽기 전용

이런 상황에서 나옵니다

"이 값은 못 고치게 하되 같이 저장되어야 해요"

보고 복사할 수는 있지만 수정할 수 없는 상태입니다.

눈으로 보기 직접 눌러보세요
헷갈리는 지점

디스에이블드와 다릅니다. 리드온리는 값이 함께 제출되고, 디스에이블드는 제출되지 않습니다. 주문서에 "회원 정보에서 가져온 이름"처럼 수정만 막고 값은 보내야 하는 경우 리드온리를 써야 합니다. 이걸 잘못 쓰면 데이터가 누락됩니다.

이렇게 요청하세요

주문자 이름은 수정 불가지만 값은 함께 제출되어야 하므로 readonly로 해주세요. disabled로 하면 값이 전송되지 않습니다.

08

트랜지션

Transition

이런 상황에서 나옵니다

"좀 더 부드럽게 해주세요" — 숫자로 바꿔 전달해야 하는 요청.

상태가 바뀔 때 뚝 끊기지 않고 부드럽게 변하는 처리입니다.

눈으로 보기 직접 눌러보세요

두 버튼에 각각 마우스를 올려보세요. 색이 바뀌는 방식이 다릅니다.

헷갈리는 지점

길이가 중요합니다. 150~300ms 정도가 자연스럽고, 500ms를 넘으면 답답해집니다. 시안에 "부드럽게"라고만 쓰면 개발자가 임의로 정하므로 숫자로 주세요.

이렇게 요청하세요

상태 변화에 트랜지션을 넣어주세요. 색·배경은 150ms, 크기·위치 변화는 250ms, 이징은 ease-out으로 통일해주세요.

09

애니메이션

Animation

이런 상황에서 나옵니다

"여기 움직임 좀 넣어주세요"

시간에 따라 요소가 움직이거나 변하는 것입니다. 트랜지션이 A→B 한 번이라면, 애니메이션은 여러 단계를 반복할 수 있습니다.

눈으로 보기 직접 눌러보세요
반복되는 애니메이션 예시
헷갈리는 지점

움직임에 민감한 사용자(어지럼증·전정기관 장애)를 위해 운영체제에 "동작 줄이기" 설정이 있습니다. 큰 애니메이션을 쓸 거라면 이 설정을 존중하도록 개발에 요청하세요.

이렇게 요청하세요

애니메이션을 넣되 prefers-reduced-motion 설정을 존중해주세요. 사용자가 OS에서 "동작 줄이기"를 켜두면 애니메이션을 끄거나 최소화해주세요.

10

이징

Easing

이런 상황에서 나옵니다

"움직임이 좀 기계적이에요"

움직임의 가속·감속 곡선입니다. 현실의 물체는 일정한 속도로 움직이지 않기 때문에, 이징이 있어야 자연스럽게 느껴집니다.

눈으로 보기 직접 눌러보세요

위: 등속(linear) · 아래: ease-out. 아래쪽이 더 자연스럽게 느껴집니다.

헷갈리는 지점

ease-out(빠르게 시작해서 천천히 멈춤)이 UI에서 가장 무난합니다. 등속(linear)은 기계적으로 느껴져서 로딩 스피너 정도에만 씁니다.

이렇게 요청하세요

이징을 ease-out으로 바꿔주세요. 등속(linear)은 기계적으로 느껴집니다. 로딩 스피너처럼 계속 도는 것만 linear로 두세요.

11

마이크로 인터랙션

Micro-interaction

이런 상황에서 나옵니다

"뭔가 심심한데 디테일 좀 넣어주세요"

아주 작은 단위의 반응입니다. 좋아요를 눌렀을 때 하트가 톡 튀는 것, 토글이 스르륵 넘어가는 것 같은 것들입니다.

눈으로 보기 직접 눌러보세요
눌러보세요
헷갈리는 지점

기능에는 영향이 없지만 "잘 만든 서비스"라는 인상을 만드는 요소입니다. 다만 모든 곳에 넣으면 산만해집니다. 사용자가 성취감을 느낄 지점에만 넣으세요.

이렇게 요청하세요

좋아요 버튼에 마이크로 인터랙션을 넣어주세요 — 누르면 하트가 살짝 커졌다 돌아오는 정도로요. 모든 요소에 넣지 말고 이 버튼에만 적용해주세요.

12

드래그 앤 드롭

Drag & Drop

이런 상황에서 나옵니다

"순서를 끌어서 바꿀 수 있게 해주세요" — 견적이 올라가는 요청.

요소를 끌어다 다른 곳에 놓는 조작입니다. 순서 변경, 파일 업로드, 칸반 보드에 씁니다.

눈으로 보기 직접 눌러보세요
할 일
디자인 검토
API 연동
완료
화면설계

항목을 끌어서 옮겨보세요. (PC 마우스 기준 — 터치 기기에서는 별도 구현이 필요합니다)

헷갈리는 지점

보기보다 구현 난도가 높아 견적이 올라갑니다. 그리고 모바일(터치)에서는 스크롤과 충돌해서 별도 처리가 필요합니다. 드래그 외에 대체 수단(위/아래 버튼)도 함께 제공해야 접근성이 확보됩니다.

이렇게 요청하세요

목록 순서를 드래그 앤 드롭으로 바꿀 수 있게 해주세요. 모바일 터치에서도 동작해야 하고, 키보드 사용자를 위해 "위로/아래로" 버튼도 함께 제공해주세요.

13

스와이프

Swipe

이런 상황에서 나옵니다

"밀어서 삭제되게 해주세요"

손가락으로 화면을 밀어 넘기는 조작입니다.

눈으로 보기 직접 눌러보세요
삭제
📧 회의 일정 안내드립니다

실제로는 손가락으로 왼쪽으로 미는 동작입니다.

헷갈리는 지점

숨어 있는 기능이라 발견성이 낮습니다. 스와이프로만 접근되는 기능이 있으면 처음 쓰는 사람은 존재 자체를 모릅니다. 반드시 다른 경로(버튼·메뉴)를 함께 두세요.

이렇게 요청하세요

목록 항목을 왼쪽으로 스와이프하면 삭제 버튼이 나오게 해주세요. 다만 스와이프만으로는 발견하기 어려우니, 각 항목의 더보기 메뉴에도 삭제를 넣어주세요.

14

롱프레스

Long Press · 길게 누르기

이런 상황에서 나옵니다

"꾹 누르면 메뉴 나오게 해주세요"

요소를 꾹 누르고 있으면 숨은 메뉴가 나타나는 조작입니다.

눈으로 보기 직접 눌러보세요
📌 이 박스를 0.7초 이상 꾹 눌러보세요
숨어 있던 메뉴가 나타났습니다
헷갈리는 지점

스와이프와 마찬가지로 발견성이 매우 낮습니다. 보조 기능에만 쓰고, 핵심 기능을 롱프레스에 숨기지 마세요. PC에는 대응되는 조작이 없어서(우클릭이 비슷) 웹에서는 잘 안 씁니다.

이렇게 요청하세요

롱프레스로 컨텍스트 메뉴를 띄우되, 같은 기능을 눈에 보이는 버튼으로도 제공해주세요. 롱프레스만으로 접근되는 기능은 대부분의 사용자가 모릅니다.

15

풀 투 리프레시

Pull to Refresh

이런 상황에서 나옵니다

"앱처럼 당겨서 새로고침되게 해주세요" — 웹에서는 주의가 필요한 요청.

화면을 아래로 당겨서 새로고침하는 조작입니다. 모바일 앱의 표준 패턴입니다.

눈으로 보기 직접 눌러보세요
새로고침 중…
헷갈리는 지점

모바일 에서는 브라우저 자체의 새로고침 동작과 충돌합니다. 웹 프로젝트에서 이걸 요구받으면 구현 난도와 부작용을 먼저 설명해야 합니다.

이렇게 요청하세요

모바일 웹에서 풀 투 리프레시는 브라우저 기본 동작과 충돌할 수 있습니다. 대신 상단에 새로고침 버튼을 두는 방식은 어떨까요? 꼭 필요하다면 구현 가능하지만 추가 공수가 듭니다.

16

패럴랙스

Parallax

이런 상황에서 나옵니다

"스크롤할 때 배경이 따로 움직이게 해주세요" — 브랜드 사이트에서.

스크롤할 때 배경과 앞쪽 요소가 서로 다른 속도로 움직여 깊이감을 주는 효과입니다.

눈으로 보기 직접 눌러보세요
배경 — 천천히 움직임
앞쪽 콘텐츠 — 정상 속도로 움직입니다.

스크롤해보세요.

배경은 뒤에 붙어 있습니다.

이 속도 차이가 깊이감을 만듭니다.
헷갈리는 지점

브랜드 사이트에는 인상적이지만, 성능 부담이 크고 멀미를 유발할 수 있습니다. 정보 전달이 목적인 서비스에는 잘 안 맞습니다. 견적에도 영향을 주는 요소라 초반에 합의하세요.

이렇게 요청하세요

히어로 섹션에만 패럴랙스를 넣어주세요. 성능 부담이 있으니 전체 페이지에는 적용하지 말고, prefers-reduced-motion 설정 시에는 꺼주세요.

17

디바운스 · 스로틀

Debounce · Throttle

이런 상황에서 나옵니다

"검색할 때마다 서버 요청이 너무 많이 나가요"

연속으로 발생하는 입력을 묶어서 처리 횟수를 줄이는 기법입니다. 디바운스는 "멈출 때까지 기다렸다 한 번", 스로틀은 "일정 간격으로 한 번씩".

눈으로 보기 직접 눌러보세요
✗ 디바운스 없음

ㅅ→서→서울→서울시 … 요청 4번 발생

✓ 디바운스 0.3초

타이핑이 멈춘 뒤 "서울시"로 요청 1번

참고로 이 사이트의 검색창에도 디바운스가 걸려 있습니다.

헷갈리는 지점

검색어 자동완성에 디바운스가 없으면 글자 하나 칠 때마다 서버에 요청이 나갑니다. "서울시청" 4글자면 요청 4번입니다. 기획서에 "입력 후 0.3초 뒤 검색"처럼 적어주면 오해가 없습니다.

이렇게 요청하세요

검색 입력에 0.3초 디바운스를 걸어주세요. 타이핑이 멈춘 뒤에만 요청이 나가야 합니다. 스크롤 이벤트에는 스로틀을 적용해주세요.

18

옵티미스틱 UI

Optimistic UI

이런 상황에서 나옵니다

"좋아요 누르면 바로 반응하게 해주세요"

서버 응답을 기다리지 않고 성공했다고 가정해서 화면을 먼저 바꾸는 방식입니다. 실패하면 되돌립니다.

눈으로 보기 직접 눌러보세요
128명이 좋아합니다

누르는 즉시 숫자가 바뀌고, 서버 저장은 그 뒤에 진행됩니다.

헷갈리는 지점

좋아요 버튼이 즉시 반응하는 게 이 원리입니다. 체감 속도가 크게 좋아지지만 실패했을 때 어떻게 되돌릴지를 반드시 함께 설계해야 합니다. 결제처럼 되돌리면 안 되는 작업에는 쓰면 안 됩니다.

이렇게 요청하세요

좋아요 버튼을 옵티미스틱 UI로 만들어주세요 — 누르는 즉시 화면을 바꾸고 서버 요청은 뒤에서 처리합니다. 실패하면 원래 상태로 되돌리고 토스트로 알려주세요.

19

지연 로딩

Lazy Loading

이런 상황에서 나옵니다

"페이지가 너무 느려요" — 이미지가 많은 페이지에서.

지금 화면에 보이는 것만 먼저 불러오고, 나머지는 스크롤해서 가까워질 때 불러오는 방식입니다.

눈으로 보기 직접 눌러보세요
✓ 이미 로딩됨 (화면에 보임)
✓ 이미 로딩됨 (화면에 보임)
↓ 스크롤해서 가까워지면 그때 불러옵니다
헷갈리는 지점

이미지가 많은 페이지의 첫 로딩 속도를 크게 개선합니다. 다만 스크롤을 빨리 내리면 이미지가 늦게 뜨는 게 보이므로, 자리(높이)를 미리 잡아두라고 요청해야 화면이 덜컹거리지 않습니다.

이렇게 요청하세요

목록 이미지에 지연 로딩을 적용해주세요. 단, 이미지 자리(width/height)를 미리 잡아둬서 로딩될 때 레이아웃이 밀리지 않게 해주세요. 첫 화면에 보이는 이미지는 지연 로딩에서 제외해주세요.