방향키로 둘러보는 동안 읽던 패널을 남깁니다

규격 탭을 읽다가 오른쪽 방향키를 눌렀더니 배송, 관리 화면이 연속해서 바뀝니다. 탭이 초점을 받는 순간 활성화되는 설계라면 자연스러운 동작일 수 있습니다. 하지만 패널을 불러오는 데 시간이 걸리거나, 내용을 둘러본 뒤 고르려는 과업에서는 초점 이동과 선택을 나누는 방식이 필요할 수 있습니다.

예제는 규격·배송·관리 세 패널을 둡니다. 방향키는 초점만 옮기고 Enter·Space 또는 클릭이 선택을 바꿉니다. 현재 읽는 패널과 조작 위치를 따로 표시해 두 상태의 차이를 볼 수 있게 했습니다.

탭 이름·선택 상태·패널을 연결합니다

<div role="tablist" aria-label="상품 안내">
  <button role="tab" id="spec-tab" aria-selected="true"
          aria-controls="spec-panel" tabindex="0">규격</button>
  <button role="tab" id="care-tab" aria-selected="false"
          aria-controls="care-panel" tabindex="-1">관리</button>
</div>
<section role="tabpanel" id="spec-panel"
         aria-labelledby="spec-tab" tabindex="0">...</section>

탭의 aria-controls는 패널을, 패널의 aria-labelledby는 그 이름을 제공하는 탭을 가리킵니다. 선택된 탭과 보이는 패널도 같은 상태여야 합니다. 속성 이름만 넣고 실제 표시가 따로 움직이면 관계가 끊깁니다.

W3C APG는 패널 표시 지연이 없을 때 자동 활성화를 권고하며, 수동 활성화 예도 제공합니다. 어느 쪽을 쓸지 정한 뒤 키보드 동작을 일관되게 구현해야 합니다. 페이지의 다른 주소로 이동하는 메뉴 링크를 단지 모양 때문에 탭 역할로 바꾸지는 않습니다.

키마다 바꾸는 상태를 구분합니다

수동 활성화 예제의 키보드 규칙
입력바뀌는 것남는 것
오른쪽·왼쪽 방향키탭의 초점선택된 탭과 패널
Home·End첫·마지막 탭으로 초점 이동선택된 패널
Enter·Space현재 초점 탭을 선택패널 이름과 선택 상태를 함께 갱신
Tab탭 목록 다음의 읽기·조작 위치불필요한 모든 탭을 순서대로 지나지 않음

수동 방식에서는 초점이 있는 탭과 선택된 탭이 잠시 다를 수 있습니다. 두 상태에 같은 테두리만 쓰면 무엇을 읽고 있는지 모호해집니다. 예제는 선택을 배경과 aria-selected로, 초점을 별도의 윤곽으로 구분합니다. 선택하지 않은 패널은 숨기고 그 안의 링크가 계속 초점을 받지 않게 합니다.

선택 처리 한 곳에서 관련 상태를 갱신합니다

function activate(tab) {
  tabs.forEach(item => {
    const selected = item === tab;
    item.setAttribute('aria-selected', String(selected));
    item.tabIndex = selected ? 0 : -1;
    document.getElementById(item.getAttribute('aria-controls'))
      .hidden = !selected;
  });
}

방향키 처리에서는 focus()만 하고 이 선택 함수를 호출하지 않습니다. 클릭이나 활성화 키에서 같은 함수를 사용하면 포인터와 키보드의 선택 규칙이 갈라지는 일을 줄일 수 있습니다. 실제 화면의 로딩 상태와 패널 안 내용은 별도로 연결해야 합니다.

선택하지 않고 나갔다 돌아오는 길도 봅니다

규격을 선택한 채 관리 탭까지 초점만 옮기고 Tab으로 나가 보세요. 패널이 그대로인지, 다시 들어왔을 때 현재 선택을 찾을 수 있는지 확인합니다. 이어서 관리 탭을 활성화하고 숨겨진 규격 패널의 링크가 남아 있는지 봅니다. 한 번 클릭해 패널이 바뀌는 장면만으로는 이 차이를 알기 어렵습니다.

패널마다 긴 표나 입력칸이 있다면 Tab의 다음 위치와 이름을 실제 보조기술에서도 확인해야 합니다. 대화상자처럼 배경을 막고 초점을 가두는 기능과는 다른 패턴입니다. 그런 창이 필요하면 대화상자 초점 설계와 분리해 구현합니다.

예제를 직접 열어 보기

이 글의 화면 예제와 소스 받기 ZIP. 압축을 푼 뒤 index.html을 브라우저에서 열 수 있습니다. 예제의 입력과 표시 범위는 각 화면의 안내를 기준으로 확인하세요.

참고한 원문