토글 및 스위치 디자인 시스템은(는) 무엇을 하나요?
목적
토글 및 스위치 디자인 시스템은 웹 인터페이스 전반에 걸쳐 이진 상태 컨트롤을 설계, 배치 및 구현하기 위한 표준화된 프레임워크를 제공합니다. 토글 스위치는 물리적인 온/오프 스위치를 나타내며, '저장' 버튼 클릭과 같은 수동 양식 제출 단계 없이 상태 변경, 환경설정 또는 기능 상태를 즉시 트리거하거나 변경합니다.
스위치 전용 디자인 시스템이 없으면 인터페이스에서 체크박스 대신 토글 스위치를 잘못 사용하거나, 비활성 상태에서 WCAG 대비 요구사항을 충족하지 못하거나, 명확한 상태 레이블이 없거나, 모바일 화면에 비해 터치 대상이 너무 작거나, 즉각적인 시각적 피드백 없이 예기치 않은 레이아웃 이동 및 배경 부작용을 유발하는 경우가 빈번합니다.
이 시스템은 스위치 형상, 트랙 및 썸 비율, 레이블 정렬, 상태 색상 매핑, 키보드 접근성(role="switch"), 터치 히트 영역 확장, 반응형 목록 레이아웃 및 비동기 대기/로딩 상태에 대한 규칙을 수립합니다.
사용 사례
- 애플리케이션 설정 및 환경설정: '푸시 알림', '다크 테마', '자동 저장 초안' 또는 '2단계 인증'과 같은 시스템 환경설정 즉시 전환.
- 구독 및 청구 기간 선택: '월간'과 '연간' 청구 주기 간 가격 책정 카드 등급을 인라인 할인 배지로 전환.
- 데이터 테이블 행 제어: 데이터 테이블 행 내에서 개별 사용자 액세스, API 통합, 웹훅 또는 자동화 규칙을 직접 활성화 또는 비활성화.
- 기능 플래그 및 시스템 모드 토글: 개발자 대시보드에서 '유지보수 모드', '디버그 로깅' 또는 '베타 기능'과 같은 운영 상태 전환.
- 개인정보 및 쿠키 동의 패널: 슬라이드 아웃 서랍 또는 모달 대화 상자 내에서 '분석 쿠키', '마케팅 쿠키'와 같은 세분화된 추적 권한 관리.
사용하지 말아야 할 경우
- 다중 옵션 선택: 상호 배타적인 3개 이상의 옵션 중에서 선택해야 하는 경우
segmented-control-system또는custom-select-and-combobox-system을 사용하십시오. - 명시적 승인이 필요한 양식 제출: 표준 다중 필드 양식 내에서 '제출' 버튼 클릭이 필요한 '이용약관에 동의합니다'와 같은 동의 조건에는
form-design-system의 표준 체크박스를 사용하십시오. - 즉시 효과가 없는 이진 선택: 컨트롤을 전환해도 별도의 '적용' 또는 '변경 사항 저장' 버튼을 누르기 전까지 효과가 적용되지 않는 경우 스위치 대신 체크박스를 사용하십시오.
- 테이블에서 대량 선택: '선택한 항목 삭제'와 같은 일괄 작업을 위해 여러 항목을 선택해야 하는 경우
data-table-ui-system의 체크박스를 사용하십시오.
입력
- 상태 정의: 이진 상태 매개변수(Off / Unchecked /
falsevs. On / Checked /true). - 컨텍스트 및 실행 모드: 즉시 클라이언트 측 상태 변경(예: 다크 테마 스위치) vs. 비동기 서버 측 부작용(예: API 웹훅 활성화/비활성화).
- 레이블 구조: 인라인 레이블 텍스트, 지원 설명/도움말 텍스트 및 상태 배지 요구 사항.
- 레이아웃 컨텍스트: 독립형 설정 카드, 밀집된 테이블 행, 다중 항목 환경설정 그룹 또는 히어로 가격 토글.
- 테마 및 토큰 팔레트: 표면 색상, 활성 트랙 색상, 비활성 트랙 색상, 썸 색상 및 포커스 링 오프셋 토큰.
출력
- 스위치 형상 및 토큰 사양: 트랙 너비, 높이, 썸 직경, 모서리 반경 및 전환 타이밍에 대한 공간 치수(
width: 44px,height: 24px,thumb: 20px). - 상태 및 대비 청사진: 기본(Off), 활성(On), 호버, 포커스-가시, 비활성화 및 대기 상태 전반에 걸쳐 트랙 및 썸에 대해 최소 WCAG 3:1 그래픽 개체 대비를 보장하는 팔레트 토큰.
- 구조적 레이아웃 및 타이포그래피 사양: 스위치 요소, 기본 레이블(
h4/span), 설명 텍스트 및 선택적 상태 표시기(ON/OFF) 간의 간격 관계. - 접근성 및 ARIA 매핑: 화면 판독기 레이블 연결(
aria-labelledby/aria-describedby)이 포함된 의미론적 HTML<button role="switch" aria-checked="true|false">구조. - 비동기 처리 프로토콜: 백그라운드 네트워크 확인을 위한 시각적 로딩 상태 사양(스피너 썸 또는 감소된 트랙 불투명도).
워크플로우
1. 컨트롤 의미 결정(스위치 vs 체크박스)
시각적 디자인 전에 상호 작용 의도가 물리적 스위치 멘탈 모델과 일치하는지 확인하십시오.
- 즉시 효과: 스위치를 전환하면 즉시 효과가 적용되거나(또는 즉시 백그라운드 요청이 트리거됨).
- 독립 실행형 작업: 명시적인 '저장' 또는 '제출' 확인 버튼 없이 독립적으로 작동.
- 온/오프 상태 은유: 다중 필드 설문지에서 선택하는 것이 아니라 기능 또는 상태를 켜거나 끄는 것을 나타냄.
2. 공간 형상 및 터치 여백 설정
데스크톱에서 시각적 조화를 유지하면서 모바일 터치 지침에 맞는 비율로 스위치 컴포넌트를 설계하십시오.
[ 비활성(OFF) 트랙 ] [ 활성(ON) 트랙 ]
+--------------------------+ +-------------------------+
| (Thumb) | -----> | (Thumb) |
| 20px | | 20px |
+--------------------------+ +-------------------------+
<-------- 44px ------------> <-------- 44px ----------->
24px height 24px height
- 표준 스위치 규모:
- 트랙 너비:
44px(또는2.75rem) - 트랙 높이:
24px(또는1.5rem) - 트랙 테두리 반경:
999px(전체 알약 모양) - 썸 직경:
20px(모든 면에2px내부 트랙 인셋 확보) - 썸 테두리 반경:
50%(원)
- 트랙 너비:
- 컴팩트/밀집형 스위치 규모 (테이블 행):
- 트랙 너비:
36px - 트랙 높이:
20px - 썸 직경:
16px(2px인셋 포함)
- 트랙 너비:
- 터치 대상 범위:
- 대화형 히트 영역은 의사 요소(
::before/::after) 또는 패딩을 사용하여 모바일 기기에서 44x44px 이상으로 확장되어야 하며, 터치스크린에서의 잘못된 클릭을 방지합니다.
- 대화형 히트 영역은 의사 요소(
3. 상태 색상 토큰 및 대비 측정항목 정의
WCAG 2.1 / 2.2 AA 비텍스트 대비 요구사항(SC 1.4.11 - 최소 3:1 대비)을 충족하려면 엄격한 색상 토큰 쌍을 따르십시오.
- 비활성(Off) 상태:
- 트랙 배경: 중성 회색 표면 (
#E2E8F0/ 다크 모드:#334155). - 트랙 테두리: 밝은 배경 표면에 대해 3:1 대비를 보장하는 1px 테두리 (
#CBD5E1/ 다크 모드:#475569). - 썸 색상: 순백색 또는 밝은 표면 (
#FFFFFF/ 다크 모드:#F8FAFC). - 썸 내부 선택적 아이콘: 이중 시각적 피드백을 위한 달/해 또는 십자/체크 아이콘 (
12px).
- 트랙 배경: 중성 회색 표면 (
- 활성(On) 상태:
- 트랙 배경: 고대비 브랜드 또는 시스템 동작 색상 (
#2563EB기본 파란색 또는#16A34A성공 녹색). 배경 페이지 표면에 대한 대비 비율은 3:1을 초과해야 합니다. - 트랙 테두리: 투명하거나 일치하는 활성 테두리.
- 썸 색상: 순백색 (
#FFFFFF)과 부드러운 CSS 전환 (200ms cubic-bezier(0.4, 0, 0.2, 1)동안transform: translateX(20px)).
- 트랙 배경: 고대비 브랜드 또는 시스템 동작 색상 (
- 호버 및 포커스 상태:
- 호버: 미묘한 트랙 밝기 변화(+5% 또는 -5%) 또는 썸 그림자 확대 (
box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.15)). - 포커스-가시: 뚜렷한 2px 오프셋 포커스 링 (
outline: 2px solid #2563EB; outline-offset: 2px).
- 호버: 미묘한 트랙 밝기 변화(+5% 또는 -5%) 또는 썸 그림자 확대 (
- 비활성화 상태:
- 트랙 및 썸 불투명도:
0.5또는0.4로 감소하고cursor: not-allowed.
- 트랙 및 썸 불투명도:
4. 레이블 정렬 및 설명 계층 구조 배치
스위치에는 항상 명확한 텍스트 레이블이 함께 제공되어야 합니다. 접근 가능한 레이블이나 가시적인 컨텍스트 없이 분리된 스위치를 제시하지 마십시오.
- 가로 행 레이아웃 (기본 환경설정 카드):
- 텍스트 블록(제목 + 설명)을 왼쪽에 배치하고 스위치를 오른쪽 가장자리에 배치합니다.
- 스위치 트랙의 세로 중앙을 제목 텍스트의 첫 번째 줄에 맞춥니다(여러 줄 설명 전체에 중앙 정렬하지 않음).
- 제목 텍스트와 스위치 요소 사이에 최소
16px간격을 유지합니다.
- 양식 인라인 레이아웃:
- 스위치를 왼쪽에, 레이블 텍스트를 오른쪽에 배치합니다(
gap: 12px). 밀집된 양식 필드 내에 스위치가 통합될 때 권장됩니다.
- 스위치를 왼쪽에, 레이블 텍스트를 오른쪽에 배치합니다(
- 가격 책정 등급 토글 레이아웃:
- 두 개의 명시적 레이블 옵션(예: '월간' — [ Switch ] — '연간 (20% 할인)') 사이에 스위치를 가로로 중앙에 배치합니다. 텍스트 레이블 또는 스위치를 클릭하면 활성 상태가 전환됩니다.
5. 비동기 부작용 및 로딩 상태 처리
스위치가 비동기 API 호출(예: 클라우드 리소스 설정 변경 또는 통합 활성화)을 트리거하는 경우:
- 낙관적 시각적 상태: 썸을 대상 위치로 즉시 슬라이드합니다(
aria-checked="true"). - 대기 중 피드백: 네트워크 지연 동안 썸 내부에 미묘한 스피너 오버레이를 렌더링하거나 트랙 불투명도를 약간 낮춥니다.
- 오류 복구: 서버가 오류를 반환하면 인라인 토스트/알림 메시지를 표시하고
aria-checked="false"와 함께 썸을 이전 상태로 부드럽게 애니메이션합니다.
6. WCAG AA 접근성 패턴 구현
모든 브라우저 엔진에서 기본 키보드 탐색 및 화면 판독기 지원을 보장합니다.
- 의미론적 HTML 마크업:
<button type="button" role="switch" aria-checked="true" id="push-notifications-switch" aria-labelledby="push-notifications-label" aria-describedby="push-notifications-desc" class="toggle-switch"> <span class="toggle-switch__track"> <span class="toggle-switch__thumb"></span> </span> </button> - 키보드 상호 작용:
Tab키 탐색을 통해 포커스 가능.Space또는Enter키를 누르면aria-checked상태(true<->false)가 전환되고 연결된 핸들러가 트리거됩니다.
- 화면 판독기 알림:
- 화면 판독기는 "푸시 알림, 스위치, 켜짐" 또는 "푸시 알림, 스위치, 꺼짐"과 같이 명시적으로 알립니다.
- 스위치의 기본 ARIA 상태를 중복하는 경우 레이블 내에 "On/Off"와 같은 텍스트를 작성하지 마십시오.
결정 규칙
스위치 vs. 체크박스 vs. 세그먼트 컨트롤 선택 매트릭스
| 시나리오 / 요구사항 | 권장 컨트롤 | 이유 |
|---|---|---|
| 즉시 효과가 있는 단일 이진 선택 (예: 다크 테마) | 토글 스위치 | 즉시 실행 모델이 물리적 스위치와 일치합니다. |
| 제출된 양식 내 단일 이진 선택 (예: 약관 동의) | 체크박스 | "제출" 버튼을 클릭하기 전까지 변경 사항이 적용되지 않습니다. |
| 목록에서 다중 항목 선택 (예: 이메일 5개 선택) | 체크박스 | 표준 일괄 선택 동작입니다. |
| 2개의 개별 모드 중에서 선택 (예: 그리드 보기 vs. 목록 보기) | 세그먼트 컨트롤 | 두 상태 레이블이 나란히 표시됩니다. |
| 모바일 목록 보기 내에서 옵션 켜기/끄기 | 토글 스위치 | 명확한 썸 대상과 명시적 상태 피드백을 제공합니다. |
레이블 위치 매트릭스
| 레이아웃 컨텍스트 | 스위치 위치 | 레이블 위치 | 공간 동작 |
|---|---|---|---|
| 설정 환경설정 목록 | 오른쪽 정렬 | 왼쪽 정렬 | 행 컨테이너 전체에 justify-content: space-between. |
| 인라인 양식 필드 | 왼쪽 정렬 | 오른쪽 정렬 | display: inline-flex; align-items: center; gap: 12px. |
| 히어로 가격 토글 | 중앙 고정 | 좌우 배치 | "월간" 및 "연간" 텍스트 옵션으로 둘러싸여 있습니다. |
제약 조건
- 접근성 (WCAG 2.1 / 2.2 AA):
- 켜짐 및 꺼짐 상태 모두에서 트랙 테두리/배경 및 썸과 페이지 배경 간의 최소 3:1 비텍스트 대비 비율.
- 연결된 모든 레이블 및 설명 도움말 텍스트에 대한 최소 4.5:1 텍스트 대비 비율.
- 포커스 링은 주변 배경에 대해 최소 3:1 대비를 제공하고 두께가 2px 이상이어야 합니다.
- 터치 대상:
- 터치 기기에서 대화형 터치 영역은 최소 44x44px 이상이어야 합니다(WCAG 2.5.5 / 2.5.8).
- 색상 독립성:
- 색상이 상태의 유일한 표시기가 되어서는 안 됩니다. 썸의 물리적 공간 위치(왼쪽 = 꺼짐, 오른쪽 = 켜짐)와 의미론적
aria-checked값은 색상과 관계없이 상태를 전달해야 합니다.
- 색상이 상태의 유일한 표시기가 되어서는 안 됩니다. 썸의 물리적 공간 위치(왼쪽 = 꺼짐, 오른쪽 = 켜짐)와 의미론적
일반적인 실패 패턴
- 제출된 양식에서 스위치 오용: 별도의 "저장" 버튼을 클릭할 때까지 변경 사항이 적용되지 않는 양식 내에서 스위치를 사용하여 즉시 적용을 기대하는 사용자에게 혼란을 줍니다.
- 부적절한 트랙 대비: 경계 테두리 없이 흰색 배경에 밝은 회색 트랙(
#F1F5F9)을 사용하여 저시력 사용자가 스위치를 볼 수 없게 만듭니다. - 색상 전용 상태 전달: 썸 슬라이더 위치를 이동하거나 ARIA 속성을 업데이트하지 않고 빨간색 대 녹색 트랙 색상에만 의존합니다.
- 매우 작은 터치 대상: 히트 영역을 36x20px 시각적 트랙으로 제한하여 모바일 뷰포트에서 불편함과 놓친 탭을 유발합니다.
- 접근성 레이블 누락:
aria-label또는aria-labelledby참조 없이 독립형 아이콘 스위치를 렌더링합니다. - 겹치는 여러 줄 텍스트: 긴 4줄 설명 문단에 대해 스위치를 세로로 중앙에 배치하여 기본 제목과의 시각적 정렬을 깨뜨립니다.
검증 기준
- 스위치가 의미론적 HTML
<button role="switch" aria-checked="true|false">구조를 사용합니다. - 트랙과 썸이 ON 및 OFF 상태 모두에서 배경에 대해 최소 3:1 대비 비율을 충족합니다.
- 키보드 탐색(
Tab,Space,Enter)이 스위치 상태를 부드럽게 전환하고aria-checked를 업데이트합니다. - 터치 히트 영역이 보이지 않는 패딩 또는 의사 요소를 사용하여 최소 44x44px로 확장됩니다.
- 스위치가
aria-labelledby를 통해 연결된 가시적이고 고대비인 레이블 텍스트와 쌍을 이룹니다. - 스위치 위치가
prefers-reduced-motion을 준수하면서 150ms~250ms 동안 부드럽게 전환됩니다(transform: translateX()). - 반응형 설정 목록이 좁은 모바일 화면에서 텍스트가 겹치지 않고 적절한 간격(
gap: 16px)을 유지합니다.