tabindex로 포커스 제어

<button> 또는 <input>와 같은 표준 HTML 요소에는 키보드 접근성이 내장되어 있으므로 가능하면 항상 사용해야 합니다. 그러나 맞춤 상호작용 요소를 빌드해야 하는 경우 tabindex를 추가하여 예상되는 사용자 동작을 생성할 수 있습니다.

브라우저 지원

  • 1
  • 12
  • 1.5
  • 4점 이하

소스

대화형 콘텐츠에만 tabindex를 추가하세요. 키 이미지와 같이 중요한 콘텐츠더라도 스크린 리더 사용자는 포커스를 추가하지 않고도 해당 콘텐츠를 이해할 수 있습니다.

tabindex란 무엇인가요?

내장 요소에서 제공하는 기본 탭 순서를 수정해야 하는 경우 tabindex HTML 속성을 사용하여 요소의 탭 위치를 명시적으로 설정할 수 있습니다.

tabindex는 모든 요소에 적용할 수 있지만 대화형 요소에만 적용되어야 하고 정수 값 범위를 사용합니다. tabindex를 사용하면 포커스 가능 페이지 요소의 명시적인 순서를 지정하고 포커스 불가능한 요소를 탭 순서에 삽입하며 탭 순서에서 요소를 삭제할 수 있습니다. 예를 들면 다음과 같습니다.

tabindex="0": 일반적인 탭 순서에 요소를 삽입합니다. Tab 키를 눌러 요소에 포커스를 둘 수 있고 focus() 메서드를 호출하여 요소에 포커스를 둘 수 있습니다.

tabindex="-1": 일반적인 탭 순서에서 요소를 삭제하지만 focus() 메서드를 호출하여 요소에 계속 포커스를 둘 수 있습니다.

tabindex="5": 0보다 큰 tabindex를 지정하면 해당 요소를 자연스러운 탭 순서 앞으로 가져옵니다. tabindex가 0보다 큰 요소가 여러 개 있다면 탭 순서는 0보다 큰 가장 낮은 값부터 시작하여 위로 올라갑니다. 0보다 큰 tabindex를 사용하는 것은 피해야 할 패턴으로 간주됩니다.

키보드를 통해 컨트롤에 액세스할 수 있는지 확인

Lighthouse와 같은 도구는 특정 접근성 문제를 자동으로 감지하는 데 유용하지만 일부 테스트는 여전히 사람이 수동으로 실행해야 합니다.

Tab 키를 눌러 사이트를 탐색해 보세요. 페이지의 모든 양방향 컨트롤에 도달할 수 있나요? 그렇지 않은 경우 tabindex를 사용하여 이러한 컨트롤의 포커스 가능 여부를 개선해야 할 수 있습니다.

페이지 수준에서 포커스 관리

tabindex가 원활한 사용자 환경을 조성하는 데 도움이 되기도 합니다. 여러 콘텐츠 섹션이 포함된 강력한 단일 페이지를 빌드하여 페이지 로드의 여러 지점에서 일부 콘텐츠가 숨겨지는 경우를 예로 들 수 있습니다. 즉, 탐색 링크가 페이지를 새로고침하지 않고도 표시되는 콘텐츠를 변경할 수 있습니다.

이 경우 선택된 콘텐츠 영역을 식별하고 tabindex-1을 부여하고 focus 메서드를 호출합니다. 이렇게 하면 콘텐츠가 자연스러운 탭 순서로 표시되지 않습니다. 포커스 관리라고 하는 이 기술은 사용자가 인식하는 컨텍스트를 사이트의 시각적 콘텐츠와 동기화된 상태로 유지합니다.

구성요소의 포커스 관리

경우에 따라 맞춤 요소를 사용할 때와 같이 컨트롤 수준에서 포커스도 관리해야 합니다.

어떤 키보드 동작을 구현할지 알기 어려울 수 있습니다. 액세스 가능한 리치 인터넷 애플리케이션 (ARIA) 작성 연습 가이드에는 구성요소 유형과 이러한 구성요소가 지원하는 키보드 작업의 종류가 나와 있습니다.

탭 순서에 요소 삽입

tabindex="0"를 사용하여 요소를 자연스러운 탭 순서에 삽입합니다. 예를 들면 다음과 같습니다.

<div tabindex="0">Focus me with the TAB key</div>

요소에 포커스를 두려면 Tab 키를 누르거나 요소의 focus() 메서드를 호출합니다.

탭 순서에서 요소 삭제

tabindex="-1"를 사용하여 요소를 삭제합니다. 예를 들면 다음과 같습니다.

<button tabindex="-1">Can't reach me with the TAB key!</button>

이렇게 하면 자연스러운 탭 순서에서 요소가 삭제되지만 focus() 메서드를 호출하여 요소에 계속 포커스를 둘 수 있습니다.

요소에 tabindex="-1"를 적용해도 하위 요소에는 영향을 미치지 않습니다. 자연스럽게 탭 순서에 있거나 tabindex 값으로 인해 하위 요소에 있는 경우 탭 순서로 유지됩니다. 탭 순서에서 요소와 모든 하위 요소를 삭제하려면 WICG의 inert 폴리필을 사용해 보세요. 폴리필은 제안된 inert 속성의 동작을 에뮬레이션하므로 보조 기술에서 요소를 선택하거나 읽을 수 없습니다.

tabindex > 0 사용 자제

tabindex가 0보다 크면 요소가 일반적인 탭 순서 앞으로 이동합니다. tabindex이 0보다 큰 요소가 여러 개 있는 경우 탭 순서는 0보다 큰 가장 낮은 값에서 시작하여 순차적으로 올라갑니다.

0보다 큰 tabindex를 사용하는 것은 피해야 할 패턴으로 간주됩니다. 스크린 리더는 탭 순서가 아닌 DOM 순서로 페이지를 탐색하기 때문입니다. 요소가 탭 순서에서 더 빨리 나오게 하려면 DOM의 이전 위치로 요소를 이동해야 합니다.

Lighthouse에서는 tabindex > 0인 요소를 식별할 수 있습니다. 접근성 감사 (Lighthouse > 옵션 > 접근성)를 실행하고 '요소가 [tabindex] 값이 0보다 큼' 감사 결과를 찾습니다.

'이동 중 tabindex' 사용

복잡한 구성요소를 빌드하는 경우 포커스 외의 키보드 지원을 추가해야 할 수도 있습니다. 가능하면 내장된 select 요소를 사용하세요. 포커스 가능하고 화살표 키를 사용하여 선택 가능한 추가 옵션을 노출할 수 있습니다.

자체 구성요소에서 비슷한 함수를 구현하려면 '이동 tabindex'이라는 기법을 사용하면 됩니다. 현재 활성 상태인 하위 요소를 제외한 모든 하위 요소에 대해 tabindex를 -1로 설정하면 이동 tabindex가 작동합니다. 그러면 구성요소는 키보드 이벤트 리스너를 사용하여 사용자가 눌렀던 키를 확인합니다.

이 경우 구성요소는 이전에 포커스를 두는 하위 요소의 tabindex를 -1로 설정하고 포커스를 둘 하위 요소의 tabindex를 0으로 설정하며 이 하위 요소에서 focus() 메서드를 호출합니다.

<div role="toolbar">
  <button tabindex="-1">Undo</button>
  <button tabindex="0">Redo</button>
  <button tabindex="-1">Cut</button>
</div>

<div role="toolbar">
  <button tabindex="-1">Undo</button>
  <button tabindex="-1">Redo</button>
  <button tabindex="0">Cut</button>
</div>

키보드 액세스 레시피

맞춤 구성요소에 필요한 키보드 지원 수준을 잘 모르겠다면 ARIA 작성 방법 1.1을 참고하세요. 이 가이드에서는 일반적인 UI 패턴을 나열하고 구성요소에서 지원해야 하는 키를 설명합니다.