로고로고

탭 접근성 개선 리팩토링 기록

2025년 4월 16일

탭 접근성 개선을 위한 리팩토링

Epigram 프로젝트를 진행하면서 탭 컴포넌트에 접근성을 고려하지 않았던 부분을 발견했습니다.

단순히 탭 클릭만으로 전환되던 기존 UI는 스크린 리더키보드 사용자에게 불친절한 구조였습니다. 이번 글에서는 접근성 개념 정리부터, 제가 어떤 속성을 어떻게 추가했고, 왜 그렇게 해야 했는지를 정리해보려 합니다.

WAI-ARIA란?

접근성을 위해 WAI-ARIA(Web Accessibility Initiative – Accessible Rich Internet Applications)라는 명세가 존재합니다. 시맨틱 HTML만으로는 부족할 수 있는 동적 UI(탭, 아코디언 등)에 역할(role)과 상태를 명시해줌으로써 보조기술이 화면을 더 잘 이해할 수 있게 해주는 속성들입니다.

 

Role 속성

role은 요소의 의미(역할)를 명시적으로 정의합니다. 시맨틱 태그를 사용하지 않거나, 커스텀 컴포넌트를 만들 경우 명확히 사용해야 합니다.

 

탭 UI에서 사용되는 대표적인 역할:

역할설명
tablist탭 버튼을 묶는 컨테이너의 역할
tab개별 탭 버튼의 역할
tabpanel각 탭에 대응하는 콘텐츠 영역의 역할

 

aria-selected

탭 중에서 어떤 탭이 선택된 상태인지를 명시해주는 속성입니다.

<button role="tab" aria-selected="true">홈</button>
<button role="tab" aria-selected="false">프로필</button>

보조기기 사용자에게 “현재 어떤 탭이 선택된 상태인지” 알 수 있게 해주는 중요한 속성입니다.

 

키보드 접근성: 방향키 이동

웹 접근성 지침에 따라, 탭 컴포넌트는 다음 키보드 조작을 지원해야 합니다:

이 처리를 위해 탭 리스트에 onKeyDown 핸들러를 달아 좌우 방향키로 activeTab을 변경하도록 구현했습니다.

 

리팩토링 내용 정리

1. TabList컴포넌트

<div role="tablist" onKeyDown={handleKeyDown}>
  {/* TabBtns */}
</div>

 

2. TabBtn 컴포넌트

<button
  role="tab"
  aria-selected={isActive}
  tabIndex={isActive ? 0 : -1}
  onFocus={() => setActiveTab(index)}
>
  탭명
</button>

 

개선 결과

항목개선 전개선 후
시맨틱 구조없음role, aria-*로 명확히 정의
키보드 접근성불가능방향키로 탭 전환 가능
보조기기 인식 가능 여부불명확스크린 리더가 현재 선택된 탭 인식 가능