포커스 표시기 디자인 시스템
목적
포커스 표시기 디자인 시스템은 모든 상호작용 요소(버튼, 링크, 양식 입력, 사용자 정의 토글 및 복잡한 위젯)에 걸쳐 키보드 포커스 표시기를 설계, 명세 및 감사하기 위한 체계적인 방법론을 제공합니다.
포커스 표시기는 키보드 탐색 사용자, 스크린 리더 사용자 및 대체 입력을 사용하는 사람들을 위한 주요 시각적 길잡이입니다. 디자이너가 기본 브라우저 포커스 링을 "보기 흉하다"는 이유로 숨기거나 저대비로 재정의하면 즉각적이고 치명적인 접근성 장벽이 생성됩니다. 이 시스템은 시각적 미학을 손상시키지 않으면서 포커스 표시기가 브랜드화되고, 고대비이며, 견고하게 배치되고, WCAG 2.1 및 2.2 표준을 준수하도록 보장합니다.
사용 사례
- 디자인 시스템 생성: 브랜드 UI 키트 내에서 전역 토큰 기반 포커스 상태를 설정합니다.
- 컴포넌트 디자인 명세: 복잡한 요소(예: 사용자 정의 체크박스, 범위 슬라이더 또는 탭 그룹)에 대한 사용자 정의 포커스 링을 정의합니다.
- 접근성 개선 감사: 기존 웹사이트에서 보이지 않거나 저대비인 포커스 아웃라인을 식별하고 수정합니다.
- 테마 및 배경 적응: 밝은, 어두운 및 브랜드 색상 배경에 대한 포커스 표시기를 표준화합니다.
- 크로스 플랫폼 입력 최적화: 마우스 사용자는 산만한 포커스 링을 보지 못하고 키보드 탐색자는 가시성이 높은 표시기를 얻을 수 있도록
:focus-visible동작을 구성합니다.
사용하지 말아야 할 경우
- 정적 콘텐츠: 비상호작용 요소(예: 일반 단락, 이미지, 헤더 또는 링크가 없는 정보 카드)에는 포커스 표시기를 디자인하지 마십시오.
- 네이티브 수정되지 않은 컨트롤: 프로젝트가 순수하게 기본 브라우저 컨트롤에 의존하고 사용자 정의 스타일링이나 브랜딩 재정의가 없으며 네이티브 포커스 동작이 완전히 변경되지 않은 경우.
- 대체 길찾기 방식: 키보드 스타일 포커스 링이 플랫폼의 표준 접근성 아키텍처의 일부가 아닌 음성 제어 스마트 디스플레이 또는 순수 터치 네이티브 모바일 애플리케이션의 경우.
입력
- 브랜드 팔레트 및 배경 토큰: 핵심 색상, 배경색(밝은, 어두운 및 브랜드 색상), 컨테이너 테두리.
- 상호작용 요소 목록: 포커스 상태가 필요한 모든 상호작용 UI 컴포넌트(버튼, 링크, 텍스트 필드, 라디오, 사용자 정의 오버레이) 목록.
- 모서리 반경 시스템: 구성 요소 둥글림에 대한 토큰 값(예:
--radius-s,--radius-m)으로 포커스 링이 요소 모양과 일치하도록 합니다. - 목표 WCAG 수준: 표준 AA 최소 준수(WCAG 2.1/2.2) 또는 AAA 목표.
출력
- 전역 포커스 토큰: 포커스 링 색상, 두께, 외곽선 스타일 및 오프셋 간격을 정의하는 표준화된 디자인 토큰.
- 구성 요소별 포커스 명세: 내부 포커스 링, 외부 포커스 링 및 복잡한 중첩 외곽선에 대한 공간 레이아웃 규칙.
- 고대비(강제 색상) 스타일 규칙: Windows 강제 색상 모드와의 호환성을 보장하는 CSS 사양.
- 포커스-가시성 통합 로직: 키보드 탐색 신호를 마우스 클릭 응답과 분리하는 명세.
워크플로우
1. 구성 요소 컨텍스트 카탈로그 작성
상호작용 구성 요소를 감사하고 컨테이너 배경별로 그룹화하여 포커스 대비 요구 사항을 결정합니다.
- 밝은 배경: 어두운 포커스 링이 필요합니다.
- 어두운 배경: 밝은 포커스 링이 필요합니다.
- 브랜드 배경(예: 선명한 파란색): 표준 브랜드 색상 외곽선은 배경과 혼합되므로 중립 흰색 또는 보조 고대비 링이 필요할 수 있습니다.
2. 크기 및 배치 모델 정의
요소와 포커스 링 사이의 기하학적 관계를 선택합니다.
- 외부 오프셋 외곽선: 포커스 링은 투명한 간격(오프셋)을 사용하여 요소 테두리 외부에 배치됩니다. 버튼, 태그 및 링크에 권장됩니다.
- 내부 포커스 링: 포커스 링이 요소 테두리 내에 배치됩니다. 텍스트 필드, 선택 메뉴 및
overflow: hidden으로 잘린 항목에 권장됩니다. - 대비 후광(이중 링): 대비되는 보조 선으로 감싸진 외부 링(예: 2px 흰색 링과 1px 검은색 외곽선). 모든 배경에 대해 가시성을 보장하므로 매우 강력합니다.
3. WCAG 대비 및 크기 토큰 설정
WCAG를 충족하기 위한 최소 스타일 값을 결정합니다.
- 포커스 링 두께를 최소 2px(3px 권장)로 설정합니다.
- 인접 배경 및 요소의 포커스되지 않은 상태에 대해 최소 3:1의 명암비를 유지합니다.
- 포커스 표시기가 컨트롤 둘레 주변의 2px 실선 테두리와 동일한 최소 표면적을 가지고 있는지 확인합니다(WCAG 2.2 포커스 모양).
4. 포인터 vs. 키보드 상태 분리
:focus-visible 의사 클래스를 활용하여 "디자인 마찰"을 방지합니다.
- 키보드 탐색 (
:focus-visible): 고대비, 시각적으로 두드러진 포커스 표시기를 트리거합니다. - 마우스/터치 상호작용 (
:focus-visible없는:focus): 마우스 클릭 시 포커스 링을 억제하거나 매우 미묘하게 유지하여 접근성을 완전히 유지하면서 디자인 불만을 방지합니다.
5. 고대비 모드 대체 정의
보조 스타일 환경 설정(예: Windows 고대비 모드/강제 색상)에서 포커스 표시기가 사라지지 않도록 합니다.
- 투명한 색상의 네이티브
outline은 강제 색상에 의해 자동으로 매핑되지만 사용자 정의box-shadow스타일은 무시됩니다. - 고대비 모드가 가시적인 외곽선을 렌더링할 수 있도록 항상
outline대체(미디어 쿼리에서outline: 2px solid transparent또는outline-color: CanvasText사용)를 포함합니다.
결정 규칙
규칙 1: 내부 vs. 외부 링 배치
- 요소에 사용자 정의 테두리가 있고 오버플로 마스크(
overflow: hidden)가 없는 경우 외부 오프셋 외곽선을 사용합니다. - 요소가 좁은 그리드의 일부이거나, 상위 컨테이너에
overflow: hidden이 있거나, 외부 외곽선이 인접 요소와 겹치는 텍스트 입력 필드인 경우 내부 포커스 링(box-shadow: inset ...)을 사용합니다.
규칙 2: 단일 색상 vs. 이중 색상 후광
- 배경이 균일하고 예측 가능하며(예: 항상 밝거나 항상 어두움) 대비가 >= 3:1로 확인된 경우 단일 색상 링을 사용합니다.
- 요소가 이미지, 그라데이션, 사용자 생성 콘텐츠 위에 있거나 다양한 배경 사이를 슬라이드하는 경우(예: 섹션 경계를 스크롤하는 고정 헤더) 이중 색상 대비 후광(예: 진한 파란색 내부, 순수 흰색 외부)을 사용합니다.
규칙 3: 포커스 링 테두리 반경
- 포커스 외곽선은 상위 컨트롤의
border-radius를 반영해야 합니다. outline-offset이 양수(예:2px또는4px)이고 외곽선의 테두리 반경이 카드/버튼 곡률과 일치하는지 확인하거나, 구성 요소의 둥근 모서리에 자연스럽게 매핑되는box-shadow를 사용합니다.
올바름:
[ 버튼 (반경 8px) ]
(간격: 2px)
============================= 포커스 외곽선 (반경 10px)
잘못됨:
[ 버튼 (반경 8px) ]
(간격: 2px)
----------------------------- 포커스 외곽선 (날카로운 90도 모서리)
제약 조건
- 접근성(대비): 포커스 링은 주변 배경에 대해 최소 3:1의 명암비를 가져야 합니다(WCAG 2.1 SC 1.4.11 비텍스트 대비).
- 접근성(가시성): 표시기가 완전히 보여야 합니다. 포커스 표시기는 고정 헤더, 플로팅 채팅 위젯 또는 오버레이 뒤에 절대 숨겨져서는 안 됩니다(WCAG 2.2 SC 2.4.11 포커스 가려짐 없음).
- 접근성(모양): 포커스 표시기는 충분히 커야 합니다. WCAG 2.2 SC 2.4.13(포커스 모양) 수학을 충족해야 합니다: 최소 2px 너비와 둘레에 2px를 곱한 값과 동일한 최소 면적.
- 반응형: 포커스 표시기는 컨테이너를 늘리거나 가로 페이지 레이아웃 오버플로를 유발해서는 안 됩니다. 항상 DOM 레이아웃 흐름을 변경하지 않는 절대 위치 지정, 절대 CSS 외곽선 또는 내부 상자 그림자를 사용합니다.
일반적인 실패 패턴
:focus { outline: none; }지우개: 강력한 의사 클래스 대체를 제공하지 않고 포커스 표시기를 완전히 숨깁니다.- 저대비 "고스트" 링: 흰색 배경에 밝은 회색 외곽선을 사용하여 저시력 사용자에게 활성 포커스 상태를 보이지 않게 만듭니다.
- "잘린 외곽선" 함정:
overflow: hidden이 있는 컨테이너 내부에 중첩된 요소에 외부 포커스 링을 배치합니다. 포커스 표시기가 왼쪽과 오른쪽에서 잘려 수평 조각만 남깁니다. - "고정 헤더 가리기": 뷰포트 상단에 있는 앵커 요소로 탭 포커스를 이동했지만 고정 탐색 모음이 이를 겹쳐 완전히 가리는 경우(WCAG 2.2 SC 2.4.11 위반).
- 클릭 유발 포커스 혼란:
:focus-visible를 사용하지 않아 모든 마우스 클릭마다 두꺼운 파란색 링이 깜빡여 디자인 팀을 좌절시키고 포커스 스타일의 완전한 제거를 요구하게 만듭니다. - 강제 색상 지우기: 투명한
outline대체 없이 CSS 사용자 정의 속성과box-shadow값만으로 아름다운 포커스 링을 구축하여 Windows 고대비 모드에서 완전히 보이지 않는 포커스 표시기를 초래합니다.
검증 기준
- 모든 상호작용 요소가
Tab키를 통해 탐색될 때 매우 잘 보이고 뚜렷한 포커스 표시기를 보여줍니다. - 모든 전역 및 구성 요소 포커스 표시기의 대비가 배경에 대해 >= 3:1로 확인됩니다.
- 사용자 정의 포커스 스타일링이
:focus-visible선택자를 사용하여 키보드 탐색시 트리거되지만 마우스 클릭시에는 깔끔하게 유지됩니다. - 상위 컨테이너
overflow: hidden규칙에 의해 포커스 표시기가 잘리거나 분할되지 않습니다(오프셋 조정 또는 내부 이동됨). - 고정 헤더 또는 플로팅 요소 근처 요소로의 키보드 탐색은 포커스된 요소를 완전히 보이게 유지합니다(
scroll-margin-top재정의 사용). - 포커스 표시기는 투명한 외곽선 규칙을 사용하여 고대비/강제 색상 모드에서 확인됩니다.
- 사용자 정의 표시기의 둘레 표면적이 WCAG 2.2 SC 2.4.13 최소 계산을 충족합니다.