Logo

HTML의 tabindex 속성과 키보드 포커스

이번 포스팅에서는 tabindex 속성을 사용해서 키보드 포커스 여부와 우선순위를 제어하는 방법에 대해서 알아보았습니다.

키보드 포커스

혹시 마우스가 고장나거나 배터리가 나가서 키보드로만 컴퓨터를 조작하거나 웹서핑을 해보신 적이 있으신가요? 마우스 사용자는 포인터로 웹페이지의 어디든지 클릭을 할 수 있지만, 키보드 사용자는 포커스라는 제한된 방법을 이용해야 되는데요.

다행히도 웹은 사용자와 상호작용(interactive)이 가능한 요소(element)는 기본적으로 키보드로 포커스가 잡히게 되어 있습니다. 대표적으로 <input>, <select>, <button> 같은 양식(form) 관련 요소(element)와 <a> 요소를 들 수 있습니다.

한번 브라우저에서 자주 방문하는 웹사이트를 열고 키보드의 tab 키를 누르고 어떤 일이 일어나는지 관찰해보세요. 이러한 상호작용하는 요소가 하나씩 차례대로 포커스가 잡히는 것을 볼 수 있을 것입니다. 반대 반향으로 탐색하려면 shift 키와 tab 키를 함께 누르면 됩니다. 이러한 부분은 마우스 대신에 키보드를 사용해야만 하는 사용자에게는 매우 중요한 부분입니다.

위 연락처 페이지에는 상호작용하는 요소가 <a> 1개, <input> 2개, <button> 1개, 이렇게 총 4개가 있습니다. 키보드의 tab 키를 누르면 <a> 요소로 이동하고, 한 번 더 누르면 첫번째 <input> 요소로 이동하고… 마지막에는 <button> 요소로 포커스가 이동할 것입니다. 그리고 여기서 한 번 더 tab 키를 누르면 포커스는 다시 <a> 요소로 돌아오게 되지요. 반대로 shift 키와 tab 키를 같이 누르면, 역방향으로 포커스가 이동하는 것을 볼 수 있을 것입니다.

<a href="#">홈으로</a>

<form>
  <h2 tabindex="0">연락처</h2>

  <p>
    <label>
      <span>이름: </span>
      <input type="text" name="name" />
    </label>
  </p>

  <p>
    <label>
      <span>이메일: </span>
      <input type="email" name="email" />
    </label>
  </p>

  <p>
    <button>제출</button>
  </p>
</form>

tabindex=“0”

만약에 상호작용하지 않는 <div><span>과 같은 요소에도 키보드 포커스가 잡히게 하고 싶을 경우에는 어떻게 해야 할까요? 해당 요소의 tabindex 속성을 0으로 설정해주면 마치 상호작용이 가능한 요소처럼 해당 요소로 포커스가 이동하게 됩니다.

예를 들어, 예제 HTML 코드에서 <h2> 요소의 tabindex 속성을 0으로 설정해보겠습니다.

<h2 tabindex="0">연락처</h2>

다시 tab 키를 눌러보면 이번에는 <a> 요소 다음에 <h2> 요소(연락처)로 키보드 포커스가 이동하는 것을 알 수 있습니다.

이 기능은 복잡한 UI를 <div><span>과 같이 tab 키로 포커스가 불가능한 요소를 기반으로 구현한 후 포커스가 오게 하고 싶을 때 주로 사용됩니다.

tabindex=“-1”

그럼 반대로 원래 상호작용하는 요소에 포커스가 잡히지 않게 하려면 어떻게 해야 할까요? 해당 요소의 tabindex 속성을 -1로 설정해주면 상호작용이 가능한 요소라도 포커스가 이동하지 않게 됩니다.

예를 들어, 예제 HTML 코드에서 <button> 요소의 tabindex 속성을 -1으로 설정해보겠습니다.

<button tabindex="-1">제출</button>

이번에 tab 키를 눌러보면 두번째 <input> 요소에 있던 포커스가 <button> 요소는 건너띄고 바로 다음 <a> 요소로 이동하는 것을 볼 수 있습니다.

참고로 어떤 요소에 tabindex="-1"을 설정하여 tab 키로 포커스가 불가능해졌더라도 자바스크립트의 focus() 함수를 이용하여 해당 요소에 포커스를 잡아줄 수 있습니다. 일반적으로 라디오 버튼 그룹처럼 여러 개의 요소로 이루어진 UI에서 하나의 요소에만 포커스가 오도록 하기 위해서 사용되는데 이 부분에 대해서는 추후 기회가 되면 다뤄보도록 하겠습니다.

tabindex=“양수”

기본적으로 키보드 포커스는 tab 키를 누르면 HTML 문서 상에서 요소들이 배치된 순서대로, shift 키와 tab 키를 함께 누르면 역순으로 이동하는데요. tabindex 속성에 1 이상의 양수값을 설정하여 요소들 간에 포커스가 잡히는 순서를 강제로 변경할 수도 있습니다.

예를 들어, 첫번째 <input> 요소의 tabindex 속성을 2로, 두번째 <input> 요소의 tabindex 속성을 1로 설정해보겠습니다.

<p>
  <label>
    <span>이름: </span>
    <input type="text" name="name" tabindex="2" />
  </label>
</p>

<p>
  <label>
    <span>이메일: </span>
    <input type="email" name="email" tabindex="1" />
  </label>
</p>

이제 tab 키를 눌러보면 두번째 <input> 요소(이메일)에 제일 먼저 포커스가 이동할 것입니다. tab 키를 한 번 더 누르면 첫번째 <input> 요소(이름)로 포커스가 이동합니다. 여기서 또 한 번 tab 키를 누르면 원래 제일 먼저 포커스가 잡히던 <a> 요소로 포커스가 이동하게 됩니다.

즉, 어떤 요소의 tabindex 속성을 양수로 지정하면 해당 요소가 HTML 문서 내에 어디에 위치하는지 상관없이 우선적으로 포커스를 받습니다. 그리고 한 HTML 문서 내에서 tabindex 속성이 양수로 지정된 요소가 여러 개라면 오름차순으로 포커스 우선순위가 설정됩니다. 다시 말해, tabindex="1", tabindex="2", tabindex="3", …, tabindex="0" 순으로 포커스가 이동하게 됩니다.

웹 접근성(accessibility) 측면에서 봤을 때 tabindex 속성을 양수로 설정하여 포커스 순서를 제어하는 것은 피해야합니다. 왜냐하면 위 예제에서 보시다시피 키보드 포커스가 중구난방으로 이동하면 사용자에게 큰 혼란을 주게 되기 때문입니다. 가급적 tabindex 속성을 사용하는 대신에 HTML 문서에 요소를 재배치하는 것이 바람직할 것입니다.

마치면서

촉박한 일정에서 웹 개발을 하다보면 키보다 사용자들까지 챙기가 어려울 때가 많은 것 같습니다. tabindex 속성을 적지적소에 잘 활용하셔서 키보드 사용자에게 좀 더 나은 경험을 제공하실 수 있길 바래봅니다.