WCAG 성공 기준 · Level A

WCAG 2.1.1: 키보드

WCAG 2.1.1은 마우스나 포인터를 통해 제공되는 모든 기능이 키보드만으로도 동일하게 조작 가능해야 하며, 키 입력에 대해 특정한 타이밍을 요구해서는 안 된다고 규정합니다. 이 기준은 마우스를 사용할 수 없는 사용자들에게 필수적인 것으로, 그들이 어떤 웹사이트나 애플리케이션에서도 탐색하고, 상호작용하며, 작업을 완료할 수 있도록 보장합니다.

이 규칙의 의미

WCAG 2.1.1(Keyboard)는 웹 페이지나 애플리케이션의 모든 기능이 키보드 인터페이스만으로 조작 가능해야 한다고 규정한다. 이는 사용자가 마우스로 버튼을 클릭하거나, 항목을 드래그하거나, 메뉴를 표시하기 위해 호버하거나, 다른 어떤 요소와 상호작용할 수 있다면, 동일한 동작을 오직 키보드 입력만으로도 수행할 수 있어야 함을 의미한다. 일반적으로 Tab, Shift+Tab, Enter, Space, 방향키가 이에 해당한다.

이 기준은 모든 인터랙티브 요소에 적용된다. 링크, 버튼, 폼 컨트롤, 커스텀 위젯, 모달 다이얼로그, 드롭다운 메뉴, 아코디언, 캐러셀, 날짜 선택기, 드래그 앤 드롭 인터페이스, 캔버스 기반 상호작용, 그리고 사용자 입력에 반응하는 기타 모든 컴포넌트가 포함된다. 콘텐츠가 사용자가 그리는 경로 자체(끝점만이 아니라 경로 전체)가 입력이 되는 드로잉 경로를 요구하는 경우만이 WCAG에서 공식적으로 인정하는 예외이다. 이 좁은 예외를 제외하면, 그 밖의 모든 기능은 키보드로 접근 가능해야 한다.

통과란 키보드만 사용하는 사용자가 Tab 또는 방향키 탐색을 통해 모든 인터랙티브 요소에 도달하고, Enter 또는 Space로 이를 활성화하며, 어떤 단계에서도 마우스를 요구하지 않고 의도된 동작을 완료할 수 있음을 의미한다. 실패는 다음 중 하나라도 해당될 때 발생한다. 인터랙티브 요소가 전혀 포커스를 받지 못하는 경우, 포커스를 받지만 요소를 활성화할 수 없는 경우, onmouseoverondblclick과 같이 마우스 이벤트로만 기능이 트리거되고 키보드에 상응하는 메커니즘이 없는 경우, 또는 스크롤 가능한 컨테이너에 키보드로 접근할 수 없어 그 안의 콘텐츠가 갇히는 경우이다.

WCAG 2.1.1과 WCAG 2.1.2(No Keyboard Trap)를 구분하는 것은 중요하다. 기준 2.1.1은 키보드 사용자가 모든 것에 도달하고 사용할 수 있도록 보장하고, 기준 2.1.2는 키보드 사용자가 어떤 컴포넌트 안에 갇히지 않도록 보장한다. 완전한 레벨 A 준수를 위해서는 두 기준 모두 충족되어야 한다.

왜 중요한가

키보드 접근성은 일부에만 해당하는 문제가 아니다. 미국에서는 성인 4명 중 1명이 어떤 형태로든 장애를 가지고 있는 것으로 추정되며, 파킨슨병, 다발성 경화증, 척수 손상, 반복성 긴장 손상(RSI), 사지 차이, 떨림과 같은 운동 장애는 종종 사용자가 일반적인 마우스나 터치스크린을 사용할 수 없게 만든다. 이러한 사용자들은 키보드, 스위치 컨트롤, sip-and-puff 장치, 헤드 포인터 또는 궁극적으로 운영체제 수준에서 키보드 입력을 에뮬레이션하는 기타 보조 기술에 전적으로 의존한다.

NVDA, JAWS, VoiceOver와 같은 스크린 리더에 의존하는 시각장애 및 저시력 사용자는 전적으로 키보드로 탐색한다. 요소가 키보드로 도달 가능하지 않다면, 스크린 리더는 그 요소를 절대 알려주지 않으며, 그 콘텐츠는 해당 사용자에게 완전히 보이지 않는 것이 된다. 세계보건기구(WHO)에 따르면 전 세계적으로 최소 22억 명이 근거리 또는 원거리 시력 손상을 가지고 있다.

구체적인 상황을 생각해 보자. 양손에 진행된 류머티즘 관절염이 있는 사용자가 전자상거래 결제 페이지를 방문한다. 사이트의 커스텀 결제 수단 선택기는 스타일이 적용된 일련의 <div> 요소로 구현되어 있으며, 마우스 클릭에만 반응한다. 사용자는 컨테이너까지는 Tab으로 이동할 수 있지만, 개별 옵션은 포커스를 받지 못하고 Enter를 눌러도 아무 일도 일어나지 않는다. 사용자는 구매를 완료할 수 없다. 이는 사소한 불편이 아니라 상업 거래에서의 완전한 배제이며, 법적 위험이자 비즈니스에 상당한 매출 손실 시나리오를 의미한다.

장애 이외에도, 키보드 접근성은 속도를 위해 키보드 단축키를 선호하는 파워 유저, 마우스 사용이 정책상 제한된 기업·정부 환경의 사용자, 비표준 입력 장치 사용자에게도 이득이 된다. 또한 검색 엔진이 더 신뢰성 있게 파싱하는 깔끔하고 시맨틱한 HTML 구조와 양의 상관관계를 가지며, 더 나은 SEO 성능과 코드베이스의 장기적인 유지보수성에 기여한다.

관련 Axe-core 규칙

  • scrollable-region-focusable: 이 규칙은 오버플로 콘텐츠(즉, 스크롤 가능)를 가진 요소가 키보드로 도달 가능한지 확인한다. 컨테이너에 overflow: autooverflow: scroll과 같은 CSS 속성이 있을 때, 시력이 있는 마우스 사용자는 마우스 휠이나 트랙패드로 이를 스크롤할 수 있다. 그러나 키보드 사용자는 Tab으로 컨테이너에 포커스를 옮기거나 방향키로 스크롤할 수 있어야 한다. 이 규칙은 tabindex 속성이 없고 자연스럽게 포커스 가능한 자식 요소도 없는 스크롤 가능한 영역을 플래그한다. 이는 키보드만 사용하는 사용자가 오버플로된 콘텐츠에 접근할 방법이 전혀 없음을 의미한다. 자동 감지는 여기서 신뢰할 수 있는데, axe가 계산된 스타일과 DOM 트리를 검사하여 키보드 포커스 기능이 없는 스크롤 오버플로 요소를 식별할 수 있기 때문이다.
  • server-side-image-map: 이 규칙은 서버 사이드 이미지 맵, 즉 ismap 속성이 있는 HTML <img> 요소의 사용을 플래그한다. 서버 사이드 이미지 맵은 마우스 클릭의 원시 픽셀 좌표를 서버로 전송하여 어떤 링크가 활성화되었는지 결정한다. 동작이 포인터 장치에서 얻은 픽셀 좌표에 전적으로 의존하기 때문에, 이에 상응하는 키보드 메커니즘은 존재하지 않는다. 반면 클라이언트 사이드 이미지 맵(<map><area> 요소 사용)은 키보드 접근 가능하게 만들 있다. 서버 사이드 이미지 맵은 근본적으로 키보드 전용 내비게이션과 양립할 수 없다. Axe는 모든 <img ismap> 요소를 키보드 접근성 실패로 플래그한다. 수동 검증에서는 해당 이미지 맵이 기저 내비게이션이나 기능에 접근하는 유일한 수단인지 여부를 확인해야 한다.

axe-core와 같은 자동화 도구는 키보드 접근성 실패의 일부만 포착할 수 있다는 점을 이해하는 것이 중요하다. 많은 위반 사항은 커스텀 JavaScript 이벤트 리스너, 동적 포커스 관리, 정적 분석만으로는 완전히 평가할 수 없는 복잡한 상호작용 패턴을 포함하기 때문에 수동 테스트가 필요하다. 예를 들어, click 이벤트 리스너가 있는 <div>로 구현된 버튼은 tabindex='0'을 통해 포커스를 받을 수 있지만, Enter나 Space 키 입력에 반응하지 못할 수 있다. 이는 상호작용을 실제로 실행하지 않고는 axe가 항상 감지할 수 없는 실패이다.

테스트 방법

  1. axe DevTools 또는 Lighthouse를 사용한 자동 스캔: Chrome 또는 Firefox용 axe DevTools 브라우저 확장 프로그램을 설치한다. 테스트할 페이지로 이동하여 전체 페이지 스캔을 실행한다. 결과를 wcag2akeyboard 태그가 있는 규칙으로 필터링한다. 특히 scrollable-region-focusableserver-side-image-map 위반을 찾아본다. Lighthouse(Chrome DevTools)에서는 접근성(A11y) 감사(Audit)를 실행하고 "Keyboard" 카테고리를 검토한다. 이러한 도구는 명백한 구조적 실패를 드러내지만, 모든 커스텀 위젯 문제를 포착하지는 못한다는 점에 유의한다.
  2. 수동 키보드 내비게이션 테스트: 마우스를 완전히 분리하거나 옆으로 치워 둔다. 브라우저 주소 표시줄에서 시작하여 Tab 키를 반복해서 눌러 페이지의 모든 포커스 가능한 요소를 앞으로 이동한다. Shift+Tab으로 뒤로 이동한다. 모든 인터랙티브 요소(링크, 버튼, 입력 필드, 커스텀 드롭다운, 모달, 슬라이더)에 대해 (a) 눈에 보이는 포커스 표시를 받는지, (b) Enter 또는 Space를 눌렀을 때 예상대로 활성화되는지, (c) 그 결과로 나타나는 다이얼로그나 패널 역시 키보드로 탐색하고 닫을 수 있는지 확인한다. 메뉴, 탭 리스트, 라디오 그룹, 리스트박스처럼 복합 패턴을 구현한 위젯 내부에서는 방향키를 사용한다.
  3. NVDA와 Firefox를 사용한 스크린 리더 + 키보드 테스트: NVDA(무료, Windows)를 실행하고 Firefox를 연다. NVDA의 브라우즈 모드(방향키)를 사용해 페이지를 읽으며 모든 인터랙티브 요소를 식별한다. 포커스 모드(Insert+Space 또는 폼 필드에서 자동 전환)로 전환하여 컨트롤과 상호작용한다. 커스텀 위젯이 역할(role), 상태(state), 이름(name)을 올바르게 알리는지, 그리고 모든 기능을 마우스 없이 완료할 수 있는지 확인한다. 스크롤 가능한 컨테이너는 Tab으로 진입을 시도하고 방향키로 스크롤이 가능한지 테스트한다.
  4. VoiceOver와 Safari(macOS/iOS)를 사용한 스크린 리더 테스트: VoiceOver를 활성화한다(macOS에서는 Command+F5). VO+오른쪽 화살표로 페이지를 선형적으로 탐색한다. Tab으로 인터랙티브 요소 간을 이동한다. 스크롤 가능한 영역에 도달할 수 있는지, 그리고 키보드로 접근 가능한 대안 없이 스와이프 제스처나 포인터 상호작용만 요구하는 기능이 없는지 확인한다.
  5. JAWS와 Chrome 테스트: JAWS를 실행한 상태에서 Chrome을 열고 페이지로 이동한다. JAWS Virtual Cursor로 콘텐츠를 탐색하고 Tab 키로 인터랙티브 요소 간을 이동한다. 아코디언, 캐러셀, 모달 다이얼로그, 커스텀 셀렉트 박스와 같은 모든 커스텀 JavaScript 위젯을, 그 위젯으로 Tab으로 이동한 뒤 키보드만으로 완전한 조작을 시도해 본다. 포커스를 받지만 활성화할 수 없는 요소나, 마우스 호버로만 접근 가능한 기능을 모두 기록한다.
  6. 스크롤 가능한 영역에 대한 특정 테스트: 페이지에서 눈에 보이는 스크롤 바가 있거나, 표시 영역보다 더 많은 콘텐츠를 포함하는 모든 컨테이너를 식별한다. 각 컨테이너에 Tab으로 진입을 시도한다. Tab이 컨테이너 내부로 포커스를 이동시키지 못하고 포커스 가능한 자식 요소도 없다면, 해당 컨테이너는 키보드 접근성 실패일 가능성이 크다. 컨테이너나 인접 요소가 포커스를 가진 상태에서 방향키를 눌러 스크롤이 가능한지 확인한다.

수정 방법

시나리오 1: 스크롤 가능한 컨테이너 — 잘못된 예

<!-- Scrollable div with no tabindex: keyboard users cannot scroll this content -->
<div style='height: 200px; overflow-y: auto;'>
  <p>Long list of terms and conditions text...</p>
  <p>More text that overflows the container...</p>
</div>

시나리오 1: 스크롤 가능한 컨테이너 — 올바른 예

<!-- Adding tabindex='0' makes the container focusable so keyboard users
     can scroll it with arrow keys once it receives focus -->
<div
  tabindex='0'
  role='region'
  aria-label='Terms and Conditions'
  style='height: 200px; overflow-y: auto;'
>
  <p>Long list of terms and conditions text...</p>
  <p>More text that overflows the container...</p>
</div>

시나리오 2: 서버 사이드 이미지 맵 — 잘못된 예

<!-- ismap sends pixel coordinates to the server — no keyboard equivalent exists -->
<a href='/map-handler'>
  <img src='navigation-map.png' ismap alt='Site navigation map' />
</a>

시나리오 2: 서버 사이드 이미지 맵 — 올바른 예

<!-- Replace with a client-side image map using <map> and <area> elements.
     Each <area> is focusable and activatable by keyboard. -->
<img
  src='navigation-map.png'
  alt='Site navigation map'
  usemap='#site-nav'
/>
<map name='site-nav'>
  <area shape='rect' coords='0,0,100,50' href='/home' alt='Home' />
  <area shape='rect' coords='100,0,200,50' href='/about' alt='About Us' />
  <area shape='rect' coords='200,0,300,50' href='/contact' alt='Contact' />
</map>

시나리오 3: 마우스 이벤트만 사용하는 커스텀 위젯 — 잘못된 예

<!-- div acting as a button with only onclick: keyboard users pressing Enter
     or Space will get no response -->
<div onclick='submitForm()'>Submit Order</div>

시나리오 3: 마우스 이벤트만 사용하는 커스텀 위젯 — 올바른 예

<!-- Option A: Use a native <button> — it handles keyboard activation natively -->
<button type='submit' onclick='submitForm()'>Submit Order</button>

<!-- Option B: If a custom element is required, add tabindex, role, and
     a keydown listener for Enter (13) and Space (32) -->
<div
  role='button'
  tabindex='0'
  onclick='submitForm()'
  onkeydown='if(event.key==="Enter"||event.key===" "){submitForm();}'
>
  Submit Order
</div>

시나리오 4: 호버 전용 드롭다운 메뉴 — 잘못된 예

<!-- Menu only appears on CSS :hover — keyboard focus on the parent
     does not reveal the submenu -->
<nav>
  <ul>
    <li class='has-dropdown'>
      <a href='/products'>Products</a>
      <ul class='dropdown'> <!-- only visible on :hover in CSS -->
        <li><a href='/products/a'>Product A</a></li>
        <li><a href='/products/b'>Product B</a></li>
      </ul>
    </li>
  </ul>
</nav>

시나리오 4: 호버 전용 드롭다운 메뉴 — 올바른 예

<!-- Use a button to toggle the dropdown and manage aria-expanded.
     CSS shows the submenu when the button has aria-expanded='true'.
     Keyboard users press Enter/Space on the button to open the menu. -->
<nav>
  <ul>
    <li class='has-dropdown'>
      <button
        aria-expanded='false'
        aria-controls='products-submenu'
        onclick='toggleMenu(this)'
      >
        Products
      </button>
      <ul id='products-submenu' hidden>
        <li><a href='/products/a'>Product A</a></li>
        <li><a href='/products/b'>Product B</a></li>
      </ul>
    </li>
  </ul>
</nav>

자주 발생하는 실수

  • 네이티브가 아닌 요소에 onclick만 이벤트 핸들러로 사용하고, 이에 상응하는 onkeydown 또는 onkeyup 핸들러를 추가하지 않는 경우 — 마우스 클릭은 onclick을 트리거하지만, <div><span>에서의 키보드 활성화는 그렇지 않다.
  • 커스텀 인터랙티브 요소에 tabindex='0'를 추가하면서 role='button'(또는 적절한 역할)을 추가하는 것을 잊어, 스크린 리더가 요소의 목적을 사용자에게 전달하지 못하게 하는 경우.
  • JavaScript 기반 키보드 토글 없이 CSS :hover 의사 클래스에만 의존하는 드롭다운 내비게이션을 구축하여, 서브메뉴가 키보드 사용자에게 보이지도, 도달 가능하지도 않게 만드는 경우.
  • 정렬 리스트, 칸반 보드, 파일 업로드 영역과 같은 드래그 앤 드롭 인터페이스를, 키보드로 트리거되는 이동 명령이나 별도의 재정렬 컨트롤과 같은 키보드 접근 가능한 대체 메커니즘 없이 구현하는 경우.
  • 서비스 약관 상자, 채팅 창, 고정 높이 래퍼 내부의 데이터 테이블과 같은 스크롤 가능한 컨테이너를 tabindex='0' 없이 생성하여, 키보드 사용자가 모든 콘텐츠를 보기 위해 스크롤할 수 없게 만드는 경우.
  • 레거시 코드베이스에서 상속된 내비게이션 컴포넌트에 <img ismap>을 사용하면서, 이를 클라이언트 사이드 이미지 맵이나 표준 내비게이션 링크로 교체하지 않는 경우.
  • 인터랙티브 요소를 자연스러운 Tab 순서에서 제거하기 위해 tabindex='-1'을 적용하면서, 프로그래매틱 포커스 관리 전략을 제공하지 않아 해당 컨트롤이 키보드로 영구적으로 도달 불가능해지는 경우.
  • 툴팁, 미리보기, 컨텍스트 메뉴와 같은 기능을 mouseenter, mouseleave, mousemove 이벤트에만 의존해 트리거하고, 이에 상응하는 focus, blur 또는 키보드 이벤트 대안을 제공하지 않는 경우.
  • 모달 다이얼로그가 포커스를 자동으로 관리한다고 가정하여, 모달이 열릴 때 포커스를 모달 내부로 이동시키지 않고, 닫힐 때 트리거 요소로 포커스를 되돌리지 않아 키보드 사용자가 페이지에서 방향 감각을 잃게 만드는 경우.
  • 키보드 접근 가능해야 하는 요소에 CSS로 pointer-events: none을 설정하는 경우. 이는 키보드 동작에 직접적인 영향을 주지는 않지만, 종종 키보드 상호작용도 차단하는 JavaScript 패턴과 함께 사용된다.

터키 접근성 규정과의 관계

터키의 대통령령 2025/10은 2025년 6월 21일 관보(Official Gazette) 제32933호에 게재되었으며, WCAG 2.1 레벨 AA에 부합하는 의무적 웹 접근성 요구사항을 수립한다. WCAG 2.1.1(Keyboard)은 레벨 A 기준으로, 요구되는 준수 사항 중 최우선 순위 계층에 속한다. 레벨 A 준수는 절대적인 최소 기준이며, 사이트가 레벨 A 기준을 충족하지 못하면 다른 개선 사항과 무관하게 비접근성으로 간주된다.

대통령령에 따라, 준수 기한은 기관 유형에 따라 구분된다. 공공 기관 및 정부 기관은 대통령령 공포일로부터 1년 이내에 준수를 달성해야 하며, 규제 대상인 민간 부문은 준수를 위해 2년의 기간이 주어진다.

대통령령 2025/10의 적용 대상에는 터키의 다양한 디지털 서비스가 폭넓게 포함된다. 전자상거래 플랫폼, 공공 기관 및 부처, 은행 및 금융 기관, 병원 및 의료 서비스 제공자, 20만 명 이상의 가입자를 보유한 통신사, 인가 여행사, 민간 운송 회사, 국가교육부(MoNE)가 인가한 사립학교 등이 이에 해당한다.

이들 모든 기관에 대해 WCAG 2.1.1을 충족하지 못한다는 것은, 키보드에 의존하는 사용자(운동 장애가 있는 시민, 고령 사용자, 스크린 리더 사용자 포함)가 핵심 디지털 서비스에 접근할 수 없음을 의미한다. 이는 직접적인 규정 위반이다. 실질적으로, 키보드만으로 결제 흐름을 완료할 수 없는 전자상거래 사이트나, 예약을 위해 마우스 상호작용이 필요한 병원 환자 포털은 대통령령 요구사항을 위반하는 것이다.

대통령령의 적용을 받는 조직은 접근성 개선 프로그램의 첫 단계로 키보드 접근성 감사를 수행해야 한다. WCAG 2.1.1 실패는 종종 HTML 요소 선택, 이벤트 바인딩 패턴, 컴포넌트 프레임워크 기본값과 같은 아키텍처적 결정에 뿌리를 두고 있기 때문에, 이를 수정하려면 단순 설정 변경이 아닌 코드 수준의 변경이 필요할 수 있다. Accsible의 오버레이 SDK는 JavaScript 레이어에서 일반적인 키보드 접근성 격차를 드러내고 패치하는 데 도움을 줄 수 있지만, 팀은 규제 검토를 충족할 수 있는 견고하고 감사 가능한 준수를 달성하기 위해 소스 코드 차원의 구조적 수정도 병행해야 한다.