테마 선택

📚 지식 노트

AI·하드웨어·주변기기·게임·컴퓨터 시스템·이론 컴퓨터 과학·수학·개발과 운영·보안·응용 분야에 대해 알아 두면 좋은 내용을 정리한 노트다. 위에서 분야를 고르고 아래에서 노트를 고른다.

인터랙션과 상태

누를 수 있어 보이게, 누르면 반응하게, 기다리거나 실패해도 알 수 있게 만드는 법이다.

목차 (13)
  1. 누를 수 있어 보이게: 시그니파이어
  2. 버튼 위계: 주·보조·텍스트 버튼
  3. 컴포넌트 상태: 기본·호버·포커스·누름·비활성·선택·로딩
  4. 포커스 링을 지우면 안 되는 이유
  5. 피드백: 즉시, 기다리는 동안, 끝났을 때
  6. 로딩 UX: 스피너, 스켈레톤, 진행률, 낙관적 UI
  7. 빈 상태와 오류 상태
  8. 실행 취소 vs 확인 대화상자
  9. 마이크로 인터랙션: 트리거·규칙·피드백·루프
  10. 토스트·스낵바·모달·시트 고르기
  11. 제스처: 보이지 않는 조작
  12. 흔한 오해
  13. 핵심 자료

누를 수 있어 보이게: 시그니파이어

화면의 모든 것은 클릭할 수 있다. 그래서 디지털 화면에서 중요한 것은 "할 수 있는가"(어포던스)보다 "할 수 있다는 것이 보이는가"(시그니파이어)다. 두 개념과 노먼의 행동 단계는 HCI와 UX 노트에 있고, 여기서는 그 신호를 화면 요소로 옮기는 법만 본다.

왼쪽은 신호 없이 글자만 둔 버튼·링크·목록 줄, 오른쪽은 채움과 테두리, 색과 밑줄, 화살표로 누를 수 있음을 알린 같은 요소신호 없음신호 있음저장저장테두리·채움이 "누르는 것"을 알린다자세히 보기자세히 보기색과 밑줄이 링크를 알린다알림 설정알림 설정켜짐오른쪽 화살표가 "들어간다"를 알린다왼쪽도 누르면 동작한다. 다만 사람이 그 사실을 알 길이 없다
같은 기능을 신호 없이 둔 것(왼쪽)과 신호를 단 것(오른쪽). 버튼은 채움과 테두리, 링크는 색과 밑줄, 들어가는 목록 줄은 오른쪽 화살표가 신호다.
  • 관례를 따른다: 사람은 다른 앱에서 배운 모양을 기대한다. 밑줄 친 파란 글자는 링크, 테두리 있는 상자는 입력 칸, 오른쪽 꺾쇠는 다음 화면이다. 새 모양을 만들면 그 뜻을 다시 가르쳐야 한다.
  • 평평한 디자인의 함정: 그림자와 테두리를 다 걷어 내면 버튼과 제목이 똑같은 글자가 된다. 장식은 줄여도 누를 수 있다는 신호 하나는 남긴다.
  • 호버에만 기대지 않는다: 마우스를 올려야 드러나는 신호는 터치 화면에서는 아예 보이지 않는다. 기본 모양만으로 알아볼 수 있어야 한다.

버튼 위계: 주·보조·텍스트 버튼

한 화면에 버튼이 여럿이면 무게를 나눈다. 가장 흔하고 바라는 다음 행동 하나를 주 버튼(채움)으로, 다른 선택을 보조 버튼(테두리)으로, 취소나 건너뛰기처럼 가벼운 것을 텍스트 버튼으로 둔다. GOV.UK 디자인 시스템도 주 버튼은 화면의 주된 행동에만 쓰고 한 페이지에 여러 개 두지 말라고 적는다.

같은 대화상자 두 개. 왼쪽은 저장이 채운 주 버튼, 임시 저장이 테두리 보조 버튼, 취소가 텍스트 버튼이고, 오른쪽은 세 버튼이 모두 같은 무게라 무엇을 누를지 바로 보이지 않는다위계 있음위계 없음변경 사항을 저장할까요?저장하지 않으면 수정한 내용이 사라집니다취소임시 저장저장변경 사항을 저장할까요?저장하지 않으면 수정한 내용이 사라집니다취소임시 저장저장텍스트 버튼보조 버튼주 버튼셋이 모두 "나를 누르라"고 외친다주 버튼은 한 화면에 하나. 나머지는 무게를 낮춰 다음 행동이 바로 보이게 한다
왼쪽은 무게가 나뉘어 저장이 먼저 보이고, 오른쪽은 세 버튼이 똑같아 하나하나 읽어야 고를 수 있다.
  • 문구는 결과를 말한다: "확인"·"예" 대신 "저장"·"삭제"처럼 누르면 일어날 일을 쓴다. 대화상자 문구만 읽지 않고 버튼만 봐도 무엇을 고르는지 안다.
  • 위험한 동작은 따로: 되돌릴 수 없는 삭제는 빨간 경고 버튼으로 구분하되, 색만이 아니라 문구로도 무엇이 일어나는지 밝힌다. GOV.UK는 경고 버튼을 쉽게 되돌릴 수 없는 심각한 동작에만 쓰라고 한다.
  • 순서는 플랫폼을 따른다: 주 버튼을 오른쪽에 두는 관례가 흔하지만 플랫폼과 디자인 시스템마다 다르다. 한 제품 안에서는 늘 같은 자리에 둔다.

컴포넌트 상태: 기본·호버·포커스·누름·비활성·선택·로딩

버튼 하나도 여러 상태를 가진다. 상태마다 모양이 달라야 사람은 "지금 눌러도 되는지, 눌렀는지, 처리 중인지"를 안다. 디자인 시안에 기본 모양만 그리고 나머지를 개발자 몫으로 남기면, 상태마다 제각각인 화면이 나온다. 상태는 처음부터 표로 정해 둔다.

버튼 하나의 일곱 가지 상태. 호버는 살짝 어둡게, 포커스는 바깥 테두리, 누름은 조금 작게, 비활성은 흐리게, 선택은 체크 표시, 로딩은 회전 표시로 구분한다저장기본누를 수 있다저장호버포인터가 위에 있다저장포커스키보드가 여기 있다저장누름입력을 받았다저장비활성지금은 못 누른다✓ 저장됨선택켜져 있다저장 중로딩처리 중이다상태마다 모양이 달라야사람이 지금을 안다
같은 버튼의 일곱 가지 상태. 호버는 살짝 어둡게, 포커스는 바깥 링, 누름은 살짝 작게, 비활성은 흐리게, 선택은 체크, 로딩은 회전 표시다.
상태언제보이는 신호주의
기본(enabled)아무 일도 없을 때누를 수 있다는 기본 모양다른 상태의 출발점
호버(hover)마우스가 위에 있을 때색을 조금 바꾸고 커서를 손 모양으로터치에는 없다. 정보를 호버에만 두지 않는다
포커스(focus)키보드·스크립트로 포커스가 왔을 때요소 둘레의 링(outline)색만 바꾸지 말고 테두리로. 아래 절
누름(pressed)누르고 있는 동안조금 작아지거나 진해짐입력을 받았다는 즉시 피드백
비활성(disabled)지금은 쓸 수 없을 때흐린 색, 반응 없음왜 못 쓰는지 알린다. 흐려도 글자는 읽혀야 한다
선택(selected)켜짐·고름이 유지될 때채움, 체크, 굵은 테두리호버·포커스와 겹쳐도 구분되게
로딩(loading)누른 동작을 처리하는 동안버튼 안 회전 표시, "저장 중"다시 누르기를 막는다(이중 제출)

NN/g의 버튼 상태 글은 비활성 상태에 aria-disabled="true"를 달아 화면 낭독기가 상태를 읽게 하라고 하고, 로딩 상태는 보통 기본 모양에 회전 표시를 더한 것이라고 설명한다. 상태는 따로 놀지 않고 사건에 따라 서로 바뀐다. 아래 그림은 그 전이를 한 단계씩 따라간다.

버튼 상태 전이 단계 그림: 기본에서 호버, 누름, 로딩을 거쳐 기본으로 돌아오고, Tab으로 포커스, 마지막에 비활성이 된다기본호버누름로딩포커스비활성기본사건: 처음저장호버사건: 포인터를 올렸다저장누름사건: 마우스 단추를 눌렀다저장로딩사건: 단추를 뗐다: 저장 요청을 보낸다저장 중로딩사건: 기다리다 한 번 더 눌렀다저장 중두 번째 누르기는 무시: 이중 제출 방지기본사건: 서버가 응답했다저장포커스사건: 키보드 Tab으로 들어왔다저장비활성사건: 필수 입력이 비어 비활성이 됐다저장왜 못 누르는지 옆에 알린다: "이메일을 입력하세요"로딩이 끝나면 "저장됨"을 잠깐 보여 준 뒤 기본으로 돌아가는 것이 흔한 마무리다
1 / 8

처음: 아무 일도 없는 기본 상태다.

사건이 생길 때마다 버튼의 상태가 바뀐다. 위 줄은 상태들이고, 지금 상태가 강조된다. 상태는 계산 함수로 구했다.

비활성 버튼은 조심해서 쓴다. 제출 버튼을 처음부터 비활성으로 두면 사용자는 무엇이 빠졌는지 모른 채 버튼만 누른다. 누를 수 있게 두고 눌렀을 때 빠진 칸을 알려 주거나, 비활성이라면 이유를 바로 옆에 적는다.

포커스 링을 지우면 안 되는 이유

브라우저는 포커스가 간 요소에 테두리(포커스 링)를 그린다. 마우스로 누를 때 이 링이 거슬린다며 outline: none으로 지우는 일이 흔한데, 그러면 키보드만으로 쓰는 사람은 지금 어디에 있는지 알 수 없다. MDN도 포커스 스타일을 지우면 눈이 보이는 키보드 사용자에게 키보드 내비게이션을 쓸 수 없게 만든다고 적는다.

Tab을 세 번 눌러 구독 버튼에 포커스가 간 화면 두 개. 포커스 표시를 지운 왼쪽은 어디에 있는지 알 수 없고, 오른쪽은 버튼 둘레에 테두리가 보인다outline: none이메일minji@example.com뉴스레터 받기구독포커스는 "구독" 버튼에 있지만 안 보인다:focus-visible 링이메일minji@example.com뉴스레터 받기구독어디에 있는지 바로 보인다Tab ×3Tab ×3마우스로 누를 때 링이 거슬리면 지우지 말고 :focus-visible로 키보드일 때만 보이게 한다
Tab을 세 번 눌러 구독 버튼에 왔다. 왼쪽은 링을 지워 포커스가 어디 있는지 모르고, 오른쪽은 :focus-visible로 다시 그려 바로 보인다.

해법은 지우는 것이 아니라 :focus-visible로 다시 그리는 것이다. 이 선택자는 브라우저가 "포커스를 보여 줘야 한다"고 판단할 때만 맞는다. 보통 마우스로 버튼을 누를 때는 맞지 않고, 키보드로 옮겨 오거나 글자를 입력할 칸에 포커스가 가면 맞는다.

/* 마우스 클릭에는 링이 없고, 키보드로 오면 또렷한 링이 생긴다 */
button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
  • 대비: MDN은 WCAG 2.1의 비텍스트 대비 기준(1.4.11)에 따라 포커스 표시가 주변과 3:1 이상 대비되어야 한다고 적는다.
  • 기준: WCAG의 2.4.7(포커스 보임, AA)은 키보드로 다루는 화면에 포커스 표시가 보이는 방식이 있어야 한다고 요구한다. 2.2에서는 포커스가 고정 헤더 같은 것에 완전히 가리지 않아야 한다는 2.4.11(AA)이 더해졌다. 키보드 내비게이션 전반은 반응형·모바일·접근성 노트에 있다.

피드백: 즉시, 기다리는 동안, 끝났을 때

사람은 누른 뒤 무슨 일이 일어나는지 계속 확인한다. 피드백은 세 시점에 필요하다. 누른 순간에는 "받았다", 기다리는 동안에는 "하고 있다", 끝나면 "됐다" 또는 "안 됐다, 이렇게 하라"다. 사람이 즉각적이라고 느끼는 0.1초, 흐름이 끊기지 않는 1초, 주의를 붙잡아 둘 수 있는 10초라는 응답 시간의 세 한계는 HCI와 UX 노트에 있다.

누른 뒤 걸리는 시간에 따른 피드백. 0.1초 안에 눌린 모양, 1초 미만이면 표시 없이 결과, 1~10초는 스피너나 스켈레톤, 10초 넘으면 진행률, 끝나면 완료 알림① 즉시: 눌림 모양0.1초 안에 "받았다"를 보인다(색·크기 변화)② 기다리는 동안: 진행 표시표시 없이 바로 결과스피너·스켈레톤진행률(%)0.1초1초2초10초30초③ 끝: 완료를 알린다"저장됨" 같은 짧은 문구, 실패면 이유와 다시 시도가로축은 로그 눈금. 구간은 NN/g의 진행 표시 기준이다
누른 순간부터 끝날 때까지의 피드백. 가로축은 로그 눈금이고, 기다리는 시간에 따라 진행 표시의 종류가 바뀐다. 구간은 계산 함수로 나눴다.

NN/g의 진행 표시 글은 이렇게 정리한다. 약 1초가 넘는 동작에는 진행 표시를 둔다. 2~10초는 반복 애니메이션(스피너)이 맞고, 10초 이상은 얼마나 됐는지 보이는 진행률을 쓴다. 1초 미만에 반복 애니메이션을 띄우면 오히려 산만하다. "로딩 중…"처럼 멈춰 있는 글자는 시스템이 멈췄는지 알 수 없게 하므로 쓰지 말고, "두 번 누르지 마세요" 같은 경고 대신 첫 번째 누름을 받았다는 것을 보이라고 한다.

로딩 UX: 스피너, 스켈레톤, 진행률, 낙관적 UI

기다림을 보여 주는 방법은 크게 셋이다. NN/g의 스켈레톤 글에 따르면 1초 안에 끝나면 아무것도 필요 없고, 스피너는 영상이나 대시보드 카드처럼 한 부분을 2~10초 기다릴 때, 스켈레톤(글과 사진 자리를 회색 막대로 먼저 그린 화면)은 페이지 전체를 10초 안쪽으로 기다릴 때 맞고, 10초를 넘으면 진행률을 강하게 권한다. 스켈레톤은 실제 화면의 모양을 미리 보여 주므로 내용이 들어와도 자리가 덜 흔들린다. 틀만 있고 모양이 없는 스켈레톤은 권하지 않는다.

로딩 표시 세 가지. 스피너는 카드 하나를 기다릴 때, 스켈레톤은 글과 사진 자리의 회색 막대로 화면 모양을 먼저 보일 때, 진행률은 50개 중 3개처럼 오래 걸리는 작업에 쓴다스피너카드 하나·2~10초스켈레톤화면 전체·10초 미만진행률10초 이상불러오는 중사진 올리는 중50장 중 3장약 2분 남음취소1초 안에 끝나면 아무것도 띄우지 않는다. 잠깐 번쩍이는 스피너는 오히려 산만하다
세 가지 로딩 표시. 스켈레톤은 실제 목록의 모양(동그란 사진과 두 줄 글)을 그대로 따른다. 진행률에는 몇 개 중 몇 개, 남은 시간, 취소를 함께 둔다.

아예 기다림을 없애는 방법도 있다. 낙관적 UI(optimistic UI)는 서버 응답을 기다리지 않고 성공했다고 보고 화면을 먼저 바꾼 뒤, 드물게 실패하면 되돌리고 알린다. React의 useOptimistic은 요청이 진행 중일 때만 낙관적 값을 보여 주고, 요청이 실패해 실제 값이 바뀌지 않으면 화면이 자연히 원래 값으로 돌아가게 만든다.

낙관적 UI 단계 그림: 왼쪽은 서버가 성공해 42개로 확정되고, 오른쪽은 서버가 실패해 41개로 되돌아가며 알림이 뜬다서버 성공누르기 전41누른 즉시(응답 전)42… 보내는 중응답 뒤42확정서버 실패누르기 전41누른 즉시(응답 전)42… 보내는 중응답 뒤41반영하지 못했습니다다시 시도쓰기 좋은 곳: 거의 항상 성공하고, 실패해도 되돌리기 쉬운 동작(좋아요, 별표, 순서 바꾸기)쓰지 않는 곳: 결제·송금처럼 실패를 나중에 알리면 곤란한 동작
1 / 3

누르기 전: 좋아요 41개. 두 경우가 같다.

좋아요 버튼의 낙관적 업데이트. 사용자는 누르는 순간 결과를 보고, 드문 실패만 뒤늦게 바로잡는다. 숫자는 계산 함수로 구했다.

낙관적 UI의 조건은 둘이다. 거의 항상 성공해야 하고, 실패했을 때 되돌려도 사용자가 손해 보지 않아야 한다. 실패 알림은 무엇이 되돌려졌는지 분명히 말하고 다시 시도를 붙인다. 오프라인에서 쌓아 두었다가 나중에 보내는 앱의 동기화 충돌은 모바일 개발 노트에 있다.

빈 상태와 오류 상태

빈 상태(empty state)는 목록이나 대시보드에 보일 것이 없는 화면이다. 처음 가입한 사람, 검색 결과가 없는 사람, 다 처리한 사람이 모두 이 화면을 본다. NN/g의 빈 상태 글은 세 가지를 권한다. 시스템 상태를 알린다(불러오는 중에는 진행 표시, 다 불러왔는데 없으면 분명한 문구). 이 기능이 무엇이고 어떻게 채우는지 가르친다. 그리고 첫 행동으로 가는 길을 둔다. 몇 초 뒤 내용으로 바뀔 "결과 없음"을 먼저 띄우면 사람은 기다리지 않고 없다고 믿어 버린다.

즐겨찾기 목록의 빈 상태 두 가지. 왼쪽은 "데이터 없음" 한 줄뿐이고, 오른쪽은 이곳에 무엇이 모이는지 설명하고 첫 즐겨찾기를 추가하는 버튼과 둘러보기 링크를 둔다막다른 빈 상태다음 행동이 있는 빈 상태즐겨찾기데이터 없음즐겨찾기별을 누른 글이 여기 모입니다인기 글 둘러보기빈 상태는 처음 온 사람이 가장 먼저 본다. 상태 알리기 → 배울 거리 → 첫 행동
즐겨찾기의 빈 상태. 왼쪽은 막다른 화면이고, 오른쪽은 무엇이 모이는 곳인지 알리고 첫 행동으로 잇는다.

오류 상태는 무엇이 안 됐는지, 사용자의 작업은 어떻게 됐는지, 이제 무엇을 하면 되는지를 알려야 한다. NN/g의 오류 메시지 지침의 요지는 이렇다. 원인 가까이에 보인다. 오류 코드 대신 사람의 말로 무엇이 문제인지 정확히 쓴다. 고치는 법을 알려 준다. 사용자를 탓하지 않는다. 그리고 입력을 지우지 않는다. 시스템 전체가 멈춘 경우라면 사과와 함께 할 수 있는 다른 일을 보여 준다.

글 저장 실패 화면 두 개. 왼쪽은 "오류가 발생했습니다 (500)"과 확인 버튼만 있고 입력이 지워졌다. 오른쪽은 쓰던 글이 남아 있고 연결이 끊겨 저장하지 못했다는 설명과 다시 시도 버튼이 있다복구할 수 없는 오류복구할 수 있는 오류내용을 입력하세요오류가 발생했습니다 (500)확인오늘 회의에서 정한 것:1. 출시일은 다음 주 화요일저장하지 못했습니다연결이 끊겼습니다. 글은 남아 있어요다시 시도입력이 지워지고, 원인과 할 일이 없다무엇이·왜·이제 어떻게, 입력은 그대로
같은 저장 실패. 왼쪽은 코드만 있고 쓰던 글이 사라졌다. 오른쪽은 글이 남아 있고, 원인과 다시 시도가 함께 있다.

입력 폼의 오류 메시지를 언제, 어디에, 어떻게 쓰는지는 폼과 입력 노트에서 따로 다룬다.

실행 취소 vs 확인 대화상자

지우는 동작을 지키는 방법은 둘이다. 하기 전에 묻는 확인 대화상자와, 바로 하고 나중에 무를 수 있게 하는 실행 취소(undo)다. NN/g는 확인 대화상자를 작업을 날리거나 돈이 들거나 되돌릴 수 없는 심각한 동작에만 쓰라고 한다. 너무 자주 물으면 사람은 읽지 않고 누르는 버릇이 들어, 정작 실수했을 때도 그대로 확인해 버린다. 그래서 되돌릴 수 있다면 실행 취소가 먼저다.

왼쪽은 삭제를 누를 때마다 정말 지울지 묻는 대화상자, 오른쪽은 바로 지우고 아래에 실행 취소를 띄우는 스낵바. 아래 막대는 메일 20통을 지우며 2통을 실수했을 때 누른 횟수와 되살린 수를 비교한다확인 대화상자메일을 삭제할까요?취소삭제바로 실행 + 실행 취소받은편지함메일 1통을 삭제했습니다실행 취소메일 20통 삭제, 그중 2통은 실수확인40번 누름 · 되살림 0통취소22번 누름 · 되살림 2통확인을 매번 물으면 버릇처럼 "삭제"를 눌러, 실수도 그대로 확인해 버린다고 가정했다
메일 20통을 지우며 2통을 실수로 지운 경우. 확인 대화상자는 매번 두 번 누르게 하지만 습관이 된 확인은 실수를 막지 못한다는 가정이다. 실행 취소는 실수일 때만 한 번 더 누른다. 횟수는 계산 함수로 구했다.
  • 되돌리기를 만들려면: 지운 것을 바로 없애지 말고 잠시 "지움 표시"만 해 두었다가 시간이 지나면 정리하거나 휴지통으로 옮긴다. 스낵바의 "실행 취소"는 그 표시를 지운다.
  • 그래도 확인이 필요하다면: 무엇이 일어나는지 구체적으로(파일 이름, 영향받는 사람 수) 쓰고, 버튼은 "예/아니요" 대신 "파일 삭제/유지"처럼 결과로 적고, "예"를 미리 골라 두지 않는다. 아주 드물고 위험한 동작에는 이름을 직접 입력하게 하는 식으로 일부러 마찰을 더한다.
  • 이 사이트의 규칙: 이 사이트의 도구들은 지우는 동작에 브라우저 confirm()을 쓰지 않는다. 브라우저가 반복된 대화상자를 막으면 confirm()이 늘 거짓을 돌려줘 삭제가 조용히 무시되기 때문이다. 곧바로 지우고 상태 줄에 되돌리기를 띄운다.

마이크로 인터랙션: 트리거·규칙·피드백·루프

마이크로 인터랙션은 좋아요 하트, 당겨서 새로 고침, 스위치 하나처럼 한 가지 일만 하는 작은 상호작용이다. NN/g는 이를 트리거와 피드백의 짝으로 정의한다. 트리거는 사용자의 동작일 수도 있고(누르기, 제스처, 음성) 정해 둔 조건을 만난 시스템일 수도 있다(알람 시각). 피드백은 그 트리거에 대한 좁고 구체적인 반응이고, 보통 트리거 가까이에 작게 나타난다. NN/g는 이 개념을 정리한 사람으로 댄 새퍼(Dan Saffer)의 2014년 책 『Microinteractions』를 든다. 이 노트는 그 책의 틀을 따라 트리거와 피드백 사이에 "무엇이 일어나는가"(규칙)를, 뒤에 "다시 쓰거나 시간이 지나면 어떻게 되는가"(루프와 모드)를 더해 네 부분으로 본다.

마이크로 인터랙션의 네 부분을 다크 모드 스위치로 본 그림. 트리거는 누르기나 시스템 조건, 규칙은 무엇이 일어나는지, 피드백은 보이는 반응, 루프와 모드는 시간이 지나거나 다시 쓸 때의 동작이다다크 모드트리거스위치를 누름또는 시스템이해 질 녘이 됨규칙테마를 바꾸고선택을 저장시스템 설정 우선피드백손잡이가 밀리고화면 색이함께 바뀜루프·모드다음에 열면 기억"자동" 모드면시간 따라 반복다음 트리거로 되돌아간다: 작은 동작 하나가 앱 전체의 인상을 만든다
다크 모드 스위치 하나를 네 부분으로 나눴다. 설계할 때 각 칸을 채워 보면 빠진 동작(시스템 설정과 충돌할 때, 다음에 열 때)이 보인다.
  • 트리거: 무엇이 시작하는가. 사용자가 시작하는 것이라면 눈에 보여야 하고, 늘 같은 자리에 있어야 한다.
  • 규칙: 시작되면 무엇이 일어나고, 무엇은 할 수 없는가. 시스템 설정이 이미 다크라면 스위치는 어떻게 보이는가 같은 경계 조건이 여기 들어간다.
  • 피드백: 규칙이 실행된 것을 어떻게 보이는가. 필요 이상으로 화려하지 않게, 정보가 되는 만큼만.
  • 루프와 모드: 두 번째, 백 번째에는 어떻게 되는가. 처음에는 알려 주던 안내를 익숙해지면 줄이고, "자동" 같은 모드가 있다면 언제 바뀌는지 정한다.

NN/g가 든 예 가운데 쇼핑몰의 하트는 누르면 짧게 뛰고, 다시 누르면 되돌아가 실행 취소 역할까지 한다. 작은 움직임을 어떻게 만드는지는 모션과 전환 노트에 있다.

토스트·스낵바·모달·시트 고르기

메시지를 띄울 자리는 성격에 따라 고른다. 질문은 셋이다. 특정 입력에 붙은 문제인가? 사용자가 답해야 다음으로 갈 수 있는가? 고를 것이 여러 개인가? NN/g는 알림을 사용자의 행동이 필요한 것과 필요 없는 것(수동적인 것)으로 나누고, 몇 초 뒤 사라지는 작은 토스트는 수동적인 알림에는 맞지만 오류 메시지에는 나쁜 선택이라고 한다.

휴대폰 화면 네 개. 인라인은 입력 칸 바로 아래 오류 문구, 스낵바는 화면 아래 짧은 알림과 실행 취소, 대화상자는 화면을 어둡게 덮고 답을 요구, 바텀 시트는 아래에서 올라온 선택지 목록이다인라인! 형식이 다릅니다한 필드의 문제바로 옆에스낵바보관했습니다취소지나가는 알림동작 하나(취소)대화상자해지할까요?해지유지답해야 진행드물게만바텀 시트링크 복사메시지로 보내기메일로 보내기고를 것이 여럿하던 일 옆에서
같은 휴대폰 화면에 띄운 네 가지 표면. 왼쪽에서 오른쪽으로 갈수록 하던 일을 더 많이 가린다. 고르는 규칙은 계산 함수와 같다.
표면막는가쓰는 곳주의
인라인 메시지아니요한 필드·한 카드의 문제원인 바로 옆에. 오류의 기본 자리
토스트·스낵바아니요"보관했습니다" 같은 결과, 실행 취소 하나저절로 사라지므로 꼭 읽어야 할 오류에 쓰지 않는다
모달 대화상자예되돌릴 수 없는 일의 경고, 진행에 꼭 필요한 입력목표와 무관한 모달(광고, 설문)은 짜증과 불신을 부른다
바텀 시트모달형은 예, 비모달형은 아니요공유 대상·정렬 기준처럼 고를 것이 여러 개뒤로 가기로 닫히게, 닫기 버튼도 두고, 시트 위에 시트를 쌓지 않는다

안드로이드의 Material 스낵바는 화면 아래쪽에 짧게 떠서 사용자를 방해하지 않고, 실행 취소나 다시 시도 같은 동작을 하나 붙일 수 있으며, 새 스낵바가 뜨면 이전 것은 사라져 한 번에 하나만 보인다. 문서는 스낵바가 동작한 맥락 안에 뜨므로 시스템 토스트보다 피드백에 더 맞다고 권한다. 모달과 바텀 시트의 지침은 NN/g의 각 글에 있다.

제스처: 보이지 않는 조작

밀기, 길게 누르기, 핀치 같은 제스처는 익숙한 사람에게는 빠른 지름길이지만 화면에 신호가 없다. 해 보기 전에는 있는지조차 모른다. 그래서 제스처는 같은 일을 하는 보이는 수단 위에 얹는 지름길로 쓴다.

제스처 다섯 가지와 흔한 뜻, 화면에 보이는 대체 수단을 나란히 적은 표. 길게 누르기에는 더 보기 버튼, 밀기에는 메뉴의 삭제, 핀치에는 확대 버튼, 끌기에는 위로·아래로 버튼을 둔다제스처흔한 뜻화면에 보이는 대체탭누르기(그 자체가 기본)길게 누르기메뉴·선택 모드"⋯ 더 보기" 버튼밀기(스와이프)삭제·보관메뉴의 "삭제"핀치확대·축소+ / − 버튼끌기순서 바꾸기"위로·아래로" 버튼제스처는 보이지 않는다. 자주 쓰는 사람에게는 지름길, 모두에게는 보이는 버튼이 있어야 한다
제스처 다섯 가지와 흔한 뜻, 그리고 같은 일을 하는 보이는 버튼. 오른쪽 열이 없으면 제스처를 모르거나 쓸 수 없는 사람은 그 기능을 쓰지 못한다.
  • 접근성 기준: WCAG 2.5.1(포인터 제스처, A)은 두 손가락 핀치나 정해진 경로로 긋는 동작이 필요한 기능을 한 손가락의 단순한 누르기로도 할 수 있어야 한다고 요구한다(W3C 설명). 2.2에서 더해진 2.5.7(끌기 동작, AA)은 끌어서 하는 일도 누르기만으로 할 수 있게 하라는 것이다.
  • 운영체제 제스처와 겹치지 않게: 화면 가장자리에서 미는 동작은 뒤로 가기나 홈 같은 시스템 제스처와 부딪힌다. 앱 제스처는 가장자리에서 떨어뜨린다.
  • 되돌릴 수 있게: 밀어서 지우기처럼 결과가 큰 제스처는 실수로 일어나기 쉽다. 위의 실행 취소를 붙인다.

흔한 오해

  • "확인 대화상자를 많이 띄울수록 안전하다" — 자주 물으면 읽지 않고 누르게 된다. 심각한 동작에만 묻고, 나머지는 실행 취소로 지킨다.
  • "포커스 링은 디자인을 해치니 지운다" — 키보드 사용자의 커서를 지우는 것과 같다. :focus-visible로 키보드일 때만 또렷하게 그린다.
  • "스피너만 띄우면 기다림은 해결된다" — 10초가 넘으면 진행률과 남은 시간이 필요하고, 1초 미만에는 스피너가 오히려 깜빡임이 된다.
  • "비활성 버튼은 실수를 막아 준다" — 왜 못 누르는지 모르면 막힌 느낌만 준다. 이유를 옆에 적거나, 누를 수 있게 두고 빠진 것을 알린다.
  • "오류는 토스트로 알리면 된다" — 저절로 사라지는 메시지는 놓치기 쉽다. 오류는 원인 옆에 남겨 둔다.
  • "제스처가 많을수록 세련된 앱이다" — 보이지 않는 조작은 배울 수 없다. 늘 보이는 대체 수단을 함께 둔다.

핵심 자료

요지는 직접 정리한 한 줄이다.

자료한 줄 요지
NN/g — Microinteractions in User Experience마이크로 인터랙션을 트리거와 피드백의 짝으로 정의하고 예를 모았다.
NN/g — Progress Indicators1초 넘으면 진행 표시, 2~10초는 반복 애니메이션, 10초 이상은 진행률.
NN/g — Skeleton Screens 101스켈레톤은 화면 전체, 스피너는 한 부분, 10초 넘으면 진행률.
MDN — :focus-visible포커스 표시를 지우지 말고 키보드일 때만 보이게 다시 그리는 법.
NN/g — Confirmation Dialogs확인은 심각한 동작에만, 결과를 이름으로 적고, 되돌리기가 먼저다.
NN/g — Error-Message Guidelines가까이, 사람 말로, 고치는 법과 함께, 입력은 지우지 않고.
NN/g — Modal & Nonmodal Dialogs모달은 막아야 할 때만. 목표와 무관한 모달은 신뢰를 깎는다.
React — useOptimistic요청 중에만 낙관적 값을 보이고, 실패하면 원래 값으로 돌아간다.