대화형 채팅 UI 시스템
목적
대화형 채팅 UI 시스템은 지속적인 온페이지 채팅 위젯, 라이브 지원 대화 상자, 자동화된 챗봇 인터페이스를 설계하고 구조화하기 위한 체계적인 방법론을 제공합니다. 채팅 창은 상호작용이 많고 콘텐츠 밀도가 높으며 공간적 제약이 있어 심각한 접근성 및 사용성 문제가 발생하기 쉽습니다.
이 시스템은 비동기 메시징 오버레이의 시각적, 구조적 디자인 문제를 해결합니다. 메시지 스트림의 가독성을 보장하고, 빠른 답장, 액션 카드와 같은 대화형 트리거에 접근 가능하게 하며, 보조 기술 사용자가 포커스 중단 없이 새 메시지를 인지할 수 있도록 하고, 모바일 오버레이가 시스템 가상 키보드와 안전 영역에 완벽하게 적응하도록 합니다.
사용 사례
- 라이브 채팅 지원 패널: 인간 고객 지원 담당자와 직접 통신할 수 있는 지속적인 위젯입니다.
- 자동화된 AI 챗봇: 온보딩, 문제 해결 또는 제품 검색을 위해 사용자를 안내하는 앱 내 또는 사이트 내 자동 비서입니다.
- 트랜잭션 대화형 양식: 대화형 상호작용으로 설계된 단계별 양식 작성입니다.
- 플로팅 도움말 센터 위젯: 지원 문서를 검색하고 라이브 채팅 스레드로 폴백하는 뷰포트 고정 오버레이입니다.
사용하지 말아야 할 경우
- 전용 이메일/받은 편지함 애플리케이션: 고밀도 다중 창 레이아웃이 필요한 대규모 전체 화면 통신 대시보드(예: Gmail, Slack, Zendesk Agent Workspace)에는
dashboard-layout-system을 사용하세요. - 전역 페이지 탐색: 보조 옵션이 아닌 이상, 지속적인 사이트 디렉토리를 채팅 기반 사이트맵으로 대체하지 마세요.
site-navigation-system을 사용하세요. - 복잡한 계층형 댓글: 중첩된 스레드 응답이 있는 블로그 또는 기사 댓글에는
comment-and-discussion-system을 사용하세요.
입력
- 대화 시나리오: 기본 흐름 매핑(사용자 시작 대 시스템 트리거, 봇 대 상담사 전환).
- 시각적 스타일 및 팔레트: 배경 표면, 수신 대 발신 버블, 상태 표시기, 포커스 표시기에 대한 디자인 토큰(
accessible-color-system및focus-indicator-design-system에서 가져옴). - 타이포그래피 스케일: 간결한 레이아웃을 위한 유연하고 가독성이 뛰어난 타이포그래피 규칙(
fluid-typography-system에서 가져옴). - 트리거 지표: 채팅 실행 버튼 또는 자동 환영 메시지가 활성화되는 시점을 결정하는 스크롤 및 이벤트 임계값.
- 대화형 미디어 자산: 파일 첨부 옵션, 이미지 미리보기 템플릿, 사용자 정의 빠른 답장 형식.
출력
- 채팅 위젯 레이아웃 사양: 플로팅 실행기 및 고정 패널에 대한 정확한 픽셀/렘 경계.
- 메시지 스레드 구조: 발신자 유형을 구분하는 컴포넌트 간격, 타이포그래피 두께, 색상 매핑.
- 반응형 모바일 청사진: 데스크톱 플로팅 패널을 모바일 전체 높이 서랍으로 변환하는 전환 규칙.
- 대화형 상태 매트릭스: 메시지 버블, 텍스트 영역, 액션 칩, 로딩 상태에 대한 시각적 피드백 맵.
- 접근성 랜드마크 청사진: ARIA 역할(
role="log",aria-live="polite",aria-busy) 및 키보드 탭 경로 맵.
워크플로
1. 플로팅 실행기(FAB) 위치 지정
플로팅 채팅 트리거 버튼은 기본 진입점이며, 주요 페이지 본문 항목을 차단하지 않고 지속적으로 유지되어야 합니다.
- 표준 위치: 실행기를 뷰포트의 오른쪽 아래 모서리에 고정합니다(RTL 레이아웃의 경우 왼쪽 아래).
- 데스크톱 그리드 오프셋: 실행기를 뷰포트 하단 및 측면 경계에서
24px만큼 오프셋합니다. - 모바일 그리드 오프셋: 콘텐츠 영역을 보존하기 위해 경계에서
16px만큼 오프셋합니다. - 충돌 완화: "맨 위로" 버튼이나 지속적인 쿠키 배너가 있는 경우, 이들을 수직으로 반대쪽에 배치하거나 최소
16px간격으로 쌓아 시각적 중첩을 방지합니다.
2. 채팅 창 컨테이너 구조화
채팅 창 컨테이너는 전체 상호작용 프레임을 포함합니다. 기본 페이지 위에 위치하며 표준 구조적 계층을 따라야 합니다.
- 헤더(프레임 앵커): 채팅 파트너(에이전트/봇)의 아바타/신원, 운영 상태(온라인 표시기, 근무 시간), 빠른 제어(최소화
_, 전체 화면/확장, 닫기X)를 포함하는 지속적인 배너입니다. - 메시지 로그 영역(스레드 뷰포트): 대화를 표시하는 스크롤 가능한 본문입니다. 스크롤 작업 중에 항상 표시되는 스크롤바로 무한 수직 스크롤을 처리해야 합니다.
- 빠른 답장 데크(브리지): 입력 표시줄 바로 위에 위치하여 한 번의 탭으로 프롬프트 응답을 제공하는 수평/래핑 가능한 대화형 칩 블록입니다.
- 입력 표시줄(고정 하단 유틸리티): 텍스트 입력 영역, 보조 유틸리티 트리거(이모지, 종이클립 파일 첨부), 기본 "보내기" 버튼으로 구성된 지속적인 양식 컨테이너입니다.
3. 메시지 버블 구조 및 리듬 디자인
빠른 스캔 가능성을 보장하려면 시각적 및 물리적 방향을 사용하여 메시지를 구분합니다.
- 발신(사용자) 메시지:
- 정렬: 오른쪽 정렬(RTL에서는 왼쪽 정렬).
- 색상: 브랜드 기본색 또는 고대비 어두운 배경에 흰색/밝은 텍스트.
- 테두리 반경: 오른쪽 아래 모서리(RTL에서는 왼쪽 아래)를 제외한 모든 모서리가 둥글게 처리되어 시각적 "말풍선" 앵커를 만듭니다.
- 수신(에이전트/봇) 메시지:
- 정렬: 왼쪽 정렬(RTL에서는 오른쪽 정렬).
- 색상: 중립적인 밝은 회색 또는 보조 브랜드 색조에 고대비 텍스트.
- 테두리 반경: 왼쪽 아래 모서리(RTL에서는 오른쪽 아래)를 제외한 모든 모서리가 둥글게 처리됩니다.
- 그룹화된 메시지: 동일한 발신자가 여러 메시지를 순차적으로 보내는 경우, 밀접하게(
4px간격) 쌓고 발신자 이름, 아바타, 타임스탬프는 마지막 버블이나 그룹 헤더에만 표시합니다. 다른 발신자 사이에는16px간격을 사용합니다. - 시스템/액션 메시지: 스레드 내에서 중앙에 배치되고, 작고, 음소거되며, 메타 이벤트를 나타내는 평평한 테두리 없는 텍스트로 스타일이 지정됩니다(예: "상담사가 채팅에 참여했습니다", "채팅 대화 내용이 이메일로 전송되었습니다").
4. 대화형 입력 영역 만들기
텍스트 입력 영역은 마찰이 가장 많이 발생하는 곳입니다. 사용성을 극대화하도록 디자인합니다.
- 자동 확장 입력: 한 줄(
최소 44px높이)로 시작하여 사용자가 입력함에 따라 세로로 확장되고(최대 4-5줄, 내부에서 세로 스크롤 활성화) 긴 메시지도 완전히 볼 수 있는<textarea>를 사용합니다. - 입력 테두리 및 호버 상태: 텍스트 영역에 뚜렷한 테두리(최소
1px, 흰색 채팅 상자에 대한 고대비3:1)를 제공합니다. 호버 시 테두리 대비가 증가해야 하며, 활성 포커스 시 고대비 포커스 링(최소2px)이 트리거되어야 합니다. - 보내기 버튼 어포던스: 텍스트 영역이 비어 있을 때 보내기 버튼은 시각적으로 비활성화(비활성화 및 음소거 불투명도)되어 있어야 합니다. 문자가 입력되면 버튼이 기본 활성 색상 상태로 전환되어 입력 준비가 되었음을 알립니다.
5. 모바일 뷰포트 적응(서랍 전환) 설정
데스크톱 채팅 상자는 작은 오버레이(보통 360px ~ 400px 너비, 500px ~ 650px 높이)입니다. 모바일에서는 이러한 비율을 사용할 수 없으며 가상 키보드와 충돌합니다.
- 전체 뷰포트 점유:
576px중단점 아래에서 채팅 컨테이너를 플로팅 패널에서 전체 화면 서랍으로 전환합니다(width: 100%; height: 100%; top: 0; left: 0; border-radius: 0;). - 가상 키보드 안전 영역: 입력 표시줄이
position: sticky; bottom: 0;을 사용하여 모바일 브라우저의 하단 주소 표시줄과 가상 키보드를 고려하여 표시되는 뷰포트 하단에 고정되도록 합니다. - 스크롤 누출 방지: 전체 화면 모바일 채팅 서랍이 활성화되어 있을 때마다
body { overflow: hidden; }또는 표준 터치 차단 클래스를 사용하여 배경 본문 스크롤을 잠급니다.
의사 결정 규칙
- 트리거 버튼 크기: 플로팅 실행기 버튼의 시각적 직경은 데스크톱 및 모바일에서 최소
56px이상이어야 하며, 쉬운 엄지손가락 활성화를 위해64x64px의 대화형 터치 범위를 가져야 합니다. - "읽지 않은 배지" 우선 순위: 패널이 최소화된 상태에서 읽지 않은 메시지가 도착하면 실행기 위에 빨간색/브랜드 색상의 숫자 배지를 표시합니다. 메시지가 매우 중요한 경우, 실행기 옆에 임시로 자체 소멸되는 텍스트 미리보기 버블을
5초동안 표시한 후 배지로 축소합니다. - 입력 중 표시기 표시: 에이전트/봇이 입력 중일 때 점 세 개가 튀는 애니메이션이 포함된 지속적인 버블을 표시합니다. 이 표시기를 가장 아래쪽 수신 메시지로 배치하지만, 실제 메시지 블록이 도착하면 즉시 제거합니다.
- 알림 타이밍 및 오디오 신호: 탭이 백그라운드에 있는 경우에만 수신 메시지에 대해 미묘하고 높은 음조의 오디오 알림을 활성화합니다. 채팅 헤더에 소리 알림을 완전히 음소거할 수 있는 명확하고 지속적인 토글을 제공합니다.
- 동적 스크롤 앵커링: 사용자가 채팅 로그 하단에 있을 때 새 메시지가 도착하면 스레드 컨테이너를 자동으로 아래로 스크롤하여 표시합니다. 그러나 사용자가 과거 기록을 읽기 위해 위로 스크롤한 경우, 갑작스러운 점프를 방지하기 위해 스크롤 위치를 잠그고 뷰포트 하단에 "새 메시지 ↓" 플로팅 알약 버튼을 표시합니다.
제약 조건
1. 접근성(WCAG AA 준수)
- 랜드마크 및 ARIA 역할:
- 기본 채팅 위젯을 랜드마크 컨테이너로 감쌉니다:
<section aria-label="고객 채팅">또는<div role="region" aria-label="지원 채팅">. - 스크롤 가능한 메시지 로그 영역은
role="log"및aria-live="polite"를 사용해야 합니다. 이는 스크린 리더가 새 메시지가 추가될 때 이를 알리되, 사용자의 활성 키보드 탐색이나 텍스트 입력을 방해하지 않도록 지시합니다. - 입력 중 표시기 버블은
aria-busy="true"를 설정하고 숨겨진 텍스트 대안(예:<span class="sr-only">지원 상담사가 입력 중입니다...</span>)을 포함해야 합니다.
- 기본 채팅 위젯을 랜드마크 컨테이너로 감쌉니다:
- 키보드 접근 및 포커스 트랩:
- 표준
Tab탐색은 헤더 컨트롤, 스크롤 가능한 메시지 스트림, 빠른 답장 칩, 입력 필드를 논리적 순서로 이동해야 합니다. - 모바일 전체 화면 채팅 서랍이 열려 있으면 키보드 포커스를 서랍 내에 가둡니다.
Escape키를 누르면 즉시 채팅 패널을 최소화하거나 닫고 포커스를 플로팅 실행기 버튼으로 되돌려야 합니다.
- 표준
- 텍스트 및 컴포넌트 대비:
- 메시지 버블 내의 모든 텍스트(수신 및 발신 모두)는 각 버블 배경에 대해 최소
4.5:1의 대비 비율을 충족해야 합니다. - 대화형 아이콘(첨부 클립, 보내기 화살표, 닫기 X) 및 양식 경계는 인접한 배경 표면에 대해 최소
3:1의 대비 비율을 충족해야 합니다.
- 메시지 버블 내의 모든 텍스트(수신 및 발신 모두)는 각 버블 배경에 대해 최소
2. 반응성 및 레이아웃 보존
- 종횡비 안정성:
- 메시지 스레드는 유연한 백분율 또는 flex-grow 모델을 사용하여 컨테이너 높이를 채우고 텍스트 오버플로우나 컨테이너 축소를 방지해야 합니다.
- 채팅 버블 내에 전송된 이미지나 카드는 채팅 레이아웃이 시각적으로 터지는 것을 방지하기 위해 고정 종횡비 또는 최대 너비 경계(버블 너비의
max-width: 80%)를 가져야 합니다.
- 레이아웃 이동 방지:
- 과거 메시지를 로드할 때(예: 위로 무한 스크롤), 스크롤 앵커링 기술을 사용하여 활성 스크롤 위치가 아래로 튀는 것을 방지하고 사용자의 뷰포트가 읽고 있던 메시지에 완벽하게 고정되도록 합니다.
일반적인 실패 패턴
- "포커스 하이재킹" 함정: 페이지 로드 시 채팅 위젯을 자동으로 열고 채팅 텍스트 영역 내에 키보드 포커스를 즉시 가둡니다. 이는 키보드 및 스크린 리더 사용자가 기본 페이지 콘텐츠를 읽는 것을 완전히 차단합니다.
- "키보드 덮어쓰기": 모바일에서
absolute좌표로 입력 표시줄을 배치하여, 활성 타이핑 중에 장치 가상 키보드가 텍스트 영역과 보내기 버튼을 덮어 숨깁니다. - "알리지 않은 스트림":
role="log"또는 `aria-live" 없이 순수하게 시각적으로만 스레드에 새 메시지를 추가하여, 시각 장애 및 저시력 사용자가 에이전트가 응답했다는 사실을 완전히 인지하지 못하게 합니다. - "스크롤 점프" 버그: 모든 수신 메시지마다 스크롤 뷰포트를 절대 하단으로 점프시켜, 스레드 상단의 과거 지침을 읽으려는 사용자를 방해합니다.
- "대비 페이드아웃" 경향: 수신 버블을 매우 밝은 회색 배경과 얇은 흰색 텍스트로 스타일링하여 대비 비율을 위반하고 일반 주변 조명에서 텍스트를 읽을 수 없게 만듭니다.
검증 기준
- 접근성 랜드마크 확인: 채팅 위젯이 설명적인
aria-label과 함께<section>또는role="region"으로 감싸져 있습니다. - 스크린 리더 알림 확인: 메시지 스레드에서
role="log"와aria-live="polite"를 사용하며 수신 텍스트를 동적으로 알리는지 확인했습니다. - 대비 검증: 발신 및 수신 버블이
4.5:1텍스트 대 배경 대비 표준을 충족하고, 양식 테두리가3:1표준을 충족합니다. - 키보드 경로 확인: 포커스 트랩이 모바일 뷰포트에서 올바르게 작동하며,
Escape키를 누르면 위젯이 닫히고 포커스가 실행기로 돌아갑니다. - 모바일 서랍 적응: 패널이
576px미만에서 100% 뷰포트 높이와 너비를 차지하며 배경 페이지 본문에 스크롤 누출이 없습니다. - 최소 터치 대상: 실행기 트리거, 닫기 버튼, 보내기 컨트롤, 빠른 답장 칩이 최소
44x44px의 대화형 범위를 가집니다. - 메시지 버블 리듬: 동일한 발신자의 연속 메시지는 좁은
4px패딩으로 클러스터링되고, 발신자 전환에는 넉넉한16px간격이 사용됩니다. - 빈 상태 가드: 입력 텍스트 영역에 공백만 포함된 경우 보내기 버튼이 비활성화되고 시각적으로 음소거됩니다.