ARIA 접근성 가이드

컴포넌트 패턴

스위치

설정을 켜짐·꺼짐으로 바로 바꾸는 스위치입니다. role="switch"와 aria-checked로 만들며, 체크박스·토글 버튼과의 차이를 정리합니다.

언제 쓰나요

스위치는 “알림 받기”, “다크 모드”, “Wi-Fi”처럼 어떤 기능을 켜거나 끄는 설정에 씁니다. 체크박스와 비슷하지만 의미가 다릅니다. 체크박스는 “이 항목을 선택했다”를, 스위치는 “이 기능이 지금 켜져 있다”를 나타냅니다. 그래서 스위치는 보통 누르는 즉시 설정이 적용됩니다.

네이티브 대안

HTML에는 스위치 전용 요소가 없습니다. 대신 이미 키보드·포커스를 갖춘 요소에 switch 역할을 얹습니다.

  • <button type="button" role="switch" aria-checked="false">: 버튼 기반. Space와 Enter 모두 동작합니다.
  • <input type="checkbox" role="switch">: 체크박스 기반. 상태는 checked로 관리되고 브라우저가 aria-checked로 전달하므로 aria-checked를 따로 쓰지 않습니다. 폼 제출 값도 그대로 유지됩니다.

스위치 역할을 지원하지 않는 오래된 보조기술은 체크박스나 토글 버튼으로 안내할 수 있습니다. 어느 쪽이든 켜짐·꺼짐 상태는 전달되므로 기능에는 문제가 없습니다.

스위치, 체크박스, 토글 버튼 비교

스위치, 체크박스, 토글 버튼 비교
구분스위치체크박스토글 버튼
마크업role="switch" + aria-checked<input type="checkbox"> 또는 role="checkbox" + aria-checked<button> + aria-pressed
상태 값true / falsetrue / false / mixedtrue / false / mixed
의미기능·설정이 켜짐 / 꺼짐항목을 선택함 / 선택 안 함버튼이 눌린 상태 / 안 눌린 상태
적용 시점보통 누르는 즉시 적용보통 폼 제출 때 함께 전송누르는 즉시 적용
대표 예알림 받기, 비행기 모드약관 동의, 관심 분야 여러 개 선택굵게, 음소거, 재생 목록 반복
안내 (예)알림 받기, 스위치, 켬약관 동의, 체크 상자, 체크 안 됨굵게, 토글 버튼, 눌림

세 가지 모두 키보드·보조기술 측면에서는 비슷하게 동작하므로, 화면에 보이는 모양과 의미가 일치하는 것을 고릅니다. 좌우로 미는 모양의 토글이라면 스위치, 네모 체크 표시라면 체크박스, 눌리는 버튼 모양이라면 토글 버튼이 자연스럽습니다.

구조

  • 스위치 요소에 switch 역할을 줍니다.
  • 상태는 aria-checked로 알리며 값은 true(켜짐) 또는 false(꺼짐)만 씁니다. 스위치에는 mixed 상태가 없습니다.
  • 이름은 기능을 설명하는 고정된 텍스트입니다(예: “알림 받기”). 버튼 안의 글자, aria-labelledby, <label> 중 하나로 줍니다.
  • 화면에 “켬/끔” 같은 상태 글자를 함께 보여 줄 수 있지만, 그 글자가 이름에 섞이거나 상태와 함께 이름이 바뀌면 안 됩니다. 상태는 aria-checked가 전달하므로, 보이는 상태 글자는 aria-hidden="true"로 숨기거나 이름 계산에서 빠지는 위치에 둡니다.
  • 여러 스위치를 묶을 때는 <fieldset>이나 group으로 묶고 묶음 이름을 줍니다.
역할과 속성 관계
<span id="noti-label">알림 받기</span>
<button type="button" role="switch" aria-checked="true"
        aria-labelledby="noti-label">
  <span class="track" aria-hidden="true"></span>
  <span class="state" aria-hidden="true">켬</span>
</button>

키보드 동작

키보드 동작
키동작
Space스위치를 켜거나 끕니다.
Enter(선택) 스위치를 켜거나 끕니다. <button> 기반 스위치는 자동으로 지원합니다.
Tab / Shift + Tab다음·이전 스위치로 이동합니다. 스위치는 각각 Tab 순서에 들어갑니다.

필요한 ARIA

필요한 ARIA
역할·속성붙이는 곳설명
switch스위치 요소켜짐·꺼짐 스위치임을 알립니다.
aria-checkedrole="switch" 요소true / false. 필수입니다. 단, <input type="checkbox" role="switch">는 checked로 상태가 전달되므로 쓰지 않습니다.
aria-labelledby 또는 aria-label스위치보이는 레이블이 스위치 바깥에 있을 때 연결합니다.
aria-describedby스위치보충 설명(예: “밤 10시~아침 8시에는 울리지 않습니다”)을 연결합니다. 선택 사항입니다.
aria-disabled스위치바꿀 수 없는 상태임을 알립니다. 네이티브 요소는 disabled를 씁니다.

aria-pressed와 함께 쓰지 않습니다

switch의 상태는 aria-checked입니다. aria-pressed는 토글 버튼(button)의 상태이므로 스위치에 붙이지 않습니다.

직접 해 보기

왼쪽은 상태에 따라 버튼 글자만 “켜짐/꺼짐”으로 바뀌는 잘못된 구현입니다. 이름 자체가 바뀌어 무엇을 켜는 버튼인지 알 수 없습니다. 가운데와 오른쪽은 올바른 구현입니다. Tab으로 이동해 Space 또는 Enter로 바꿔 보세요.

잘못된 구현

알림 받기

버튼 이름이 “꺼짐”, “켜짐”으로 바뀌고 무엇을 켜는지 연결되어 있지 않습니다. 상태 속성도 없습니다.

올바른 구현: 버튼 기반

알림 받기

올바른 구현: 체크박스 기반

checked 상태가 그대로 스위치 상태로 전달됩니다.

전체 코드

비권장비권장: 상태에 따라 이름이 바뀜
<span>알림 받기</span>
<button type="button" onclick="this.textContent =
  this.textContent === '켜짐' ? '꺼짐' : '켜짐'">꺼짐</button>
권장권장: 고정된 이름 + aria-checked
<span id="noti-label">알림 받기</span>
<button type="button" role="switch" id="noti"
        aria-checked="false" aria-labelledby="noti-label">
  <span class="track" aria-hidden="true"></span>
</button>
버튼 기반 스위치 (JavaScript)
var sw = document.getElementById('noti');

// <button>은 Space와 Enter 모두 click 이벤트를 발생시킵니다.
sw.addEventListener('click', function () {
  var on = sw.getAttribute('aria-checked') === 'true';
  sw.setAttribute('aria-checked', String(!on));
  // 여기서 실제 설정을 바로 적용합니다. 예: saveSetting('notification', !on);
});
체크박스 기반 스위치 (HTML만으로 동작)
<input type="checkbox" role="switch" id="dark">
<label for="dark">다크 모드</label>
CSS (상태를 aria-checked로 표시)
[role="switch"][aria-checked="true"] .track { background: #1a5fb4; }

/* 상태를 속성 선택자로 그리면 화면과 ARIA 상태가 어긋날 수 없습니다. */
[role="switch"][aria-checked="true"] .track::after { transform: translateX(1.25rem); }

div로 만들어야 한다면

<div role="switch">를 쓰면 tabindex="0"을 주고 Space(가능하면 Enter도) 키 처리를 직접 넣어야 합니다. <button>을 쓰면 이 작업이 모두 필요 없습니다.

화면낭독기에서는

화면낭독기 안내 예시 (표현은 화면낭독기·브라우저·버전에 따라 조금씩 다릅니다)
상황들리는 안내 (예)
꺼진 스위치에 포커스알림 받기, 스위치, 끔
Space로 켬켬
스위치 역할을 모르는 보조기술알림 받기, 체크 상자, 체크됨 (체크박스로 대체 안내)
잘못된 구현에 포커스 후 누름꺼짐, 버튼 → 켜짐, 버튼 (무엇을 켜는지 알 수 없음)

점검 체크리스트

  • <button> 또는 <input type="checkbox">에 role="switch"를 얹어 만들었습니다.
  • aria-checked 값이 true/false 중 하나이며 실제 설정 상태와 일치합니다(mixed를 쓰지 않음).
  • 체크박스 기반 스위치에는 aria-checked를 덧붙이지 않았습니다.
  • 접근 가능한 이름이 기능을 설명하고, 상태가 바뀌어도 이름은 바뀌지 않습니다.
  • 보이는 “켬/끔” 글자가 이름에 섞이지 않습니다.
  • Space로 바뀌며, 버튼 기반이면 Enter도 동작합니다.
  • 켜짐·꺼짐이 색만이 아니라 손잡이 위치·글자로도 구분되고, 테두리가 배경과 3:1 이상 대비됩니다.
  • 포커스 표시가 분명하게 보입니다.

관련 WCAG 성공 기준

참고 자료