AI가 만든 화면을 마우스로 눌러 보고 배포하려는 순간, 마우스를 잠깐 치워 보자. 가입 버튼까지 갈 수 있는지, 지금 선택된 곳이 보이는지, 열린 창에서 다시 나올 수 있는지가 드러난다. 예쁜 화면과 끝까지 사용할 수 있는 화면 사이의 빈틈을 찾는 출발점이다.
이 글은 공개된 W3C와 MDN 문서를 바탕으로 만든 바이브 코딩용 점검 절차다. 특정 서비스에서 장애를 발견했다거나 개선 성과를 측정했다는 사례가 아니다. 키보드 점검만으로 접근성 전체가 충족되는 것도 아니다.
먼저 하나의 사용자 과업을 정한다
‘사이트 접근성을 고쳐 줘’ 대신 작은 과업을 고른다. 예를 들어 ‘상품 목록에서 상세를 열고, 알림 설정을 확인한 뒤 목록으로 돌아오기’다. 시작 위치와 완료 상태를 적어 두면 AI가 바꾼 부분을 같은 순서로 다시 확인할 수 있다.
- 브라우저와 운영체제의 키보드 탐색 설정을 확인한다. 환경에 따라 링크에 Tab으로 접근하는 설정이 다를 수 있다.
- 페이지를 새로 열고 Tab과 Shift+Tab으로 앞뒤를 오간다. 마우스 클릭으로 막힌 구간을 건너뛰지 않는다.
- 링크는 Enter, 일반 버튼은 Enter와 Space로 동작을 확인한다. 선택 상자나 탭처럼 별도 패턴이 있는 위젯은 해당 패턴의 키 규칙도 확인한다.
- 화면 위치, 누른 키, 기대 결과, 실제 결과를 한 줄씩 남긴다. ‘안 됨’보다 다시 따라 할 수 있는 기록이 수정에 도움이 된다.
버튼처럼 보인다면 먼저 HTML 요소를 본다
화면에서는 같은 사각형이어도 클릭 이벤트만 붙인 div와 button은 기본 동작이 다르다. 동작을 실행하는 것은 button, 다른 주소로 이동하는 것은 href가 있는 a를 우선 검토한다. role만 추가했다고 키보드 처리까지 생기지는 않는다.
<!-- 현재 화면에서 동작 실행 -->
<button type="button" id="open-settings">알림 설정 열기</button>
<!-- 다른 주소로 이동 -->
<a href="/help/">도움말 읽기</a>폼 안에서 제출용이 아닌 버튼에는 type="button"을 명시한다. 아이콘만 있는 버튼은 사용자가 목적을 알 수 있는 이름도 필요하다. 이름을 넣었더라도 동작이 맞는지는 별도로 눌러 본다.
포커스는 ‘어디에 있는지’와 ‘어디로 가는지’를 함께 본다
Tab을 눌러 요소에 도달해도 표시가 보이지 않으면 현재 위치를 알 수 없다. outline을 없애기 전에 대체 표시부터 마련한다. 아래는 시작용 예시다. 실제 배경과 테두리에서 구분되는지, 고대비 모드에서도 식별되는지는 제품에서 확인해야 한다.
:where(a, button, input, select, textarea):focus-visible {
outline: 3px solid #1a1a1a;
outline-offset: 3px;
}시각적으로 두 번째인 버튼이 키보드로는 마지막에 나온다면 숫자 tabindex를 잔뜩 붙여 순서를 맞추기보다 DOM 순서와 화면 배치를 먼저 비교한다. 숨겨진 메뉴에 초점이 가거나 고정 배너 뒤에 가려지는지도 확인한다. 순서와 표시를 따로 통과시켜야 놓치는 구간이 줄어든다.
포커스 표시의 목적과 주의점: W3C Focus Visible ↗

모달은 열기보다 닫은 뒤를 놓치기 쉽다
모달을 열면 포커스가 내부로 들어가고, 열려 있는 동안 Tab과 Shift+Tab은 내부에서 이동해야 한다. 닫기 버튼과 Escape로 종료할 수 있어야 하며, 닫은 뒤에는 보통 열었던 버튼으로 돌아간다. 그 버튼이 사라졌다면 다음 과업에 맞는 위치를 정해야 한다.
네이티브 dialog의 showModal()은 배경을 비활성화하는 기본 동작을 제공한다. 직접 모든 키 처리를 만드는 것보다 검토할 출발점이 명확하다. 다음 코드는 짧은 안내창 예시이며 실제 저장 기능이나 모든 제품의 포커스 정책을 대신하지 않는다.
<button type="button" id="opener">안내 열기</button>
<dialog id="notice" aria-labelledby="notice-title">
<h2 id="notice-title">알림 안내</h2>
<p>알림 설정은 계정 화면에서 바꿀 수 있습니다.</p>
<form method="dialog">
<button autofocus>닫기</button>
</form>
</dialog>
<script>
const opener = document.querySelector("#opener");
const notice = document.querySelector("#notice");
opener.addEventListener("click", () => notice.showModal());
</script>긴 설명이나 삭제 확인창에서는 첫 포커스 위치를 다르게 설계할 수 있다. 위 예시처럼 항상 닫기 버튼에 autofocus를 붙이는 규칙으로 일반화하지 않는다. 실제 브라우저에서 열기 → 내부 이동 → Escape → 다시 열기 → 닫기 버튼 순서로 시험하고, 두 종료 경로 모두 돌아오는 위치를 확인한다.

AI에게는 증상과 재검사 경로를 같이 준다
알림 설정 화면에서 키보드만 사용하면 열기 버튼에 도달하지 못합니다. 클릭 전용 요소와 DOM 순서를 먼저 확인해 주세요. 동작은 네이티브 button을 우선 사용하고 기존 제출 동작은 바꾸지 마세요. 수정 뒤 Tab으로 열기 → Enter로 실행 → 내부 앞뒤 이동 → Escape로 닫기 → 원래 위치 복귀를 확인할 수 있도록 변경점과 검사 절차를 알려 주세요.
재현하지 않은 증상을 사실처럼 넣지 않는다. 위 문장은 실제로 해당 문제가 확인됐을 때 바꿔 쓰는 요청 예시다. ‘접근성 완료’라는 답을 받더라도 실행한 검사, 실패한 검사, 아직 하지 않은 검사를 나눠 달라고 요청한다.
배포 전 남길 작은 확인표
- 도달: 주요 과업의 모든 조작 요소까지 키보드로 갈 수 있는가?
- 표시: 현재 포커스가 눈에 보이고 다른 요소 뒤에 가려지지 않는가?
- 실행: 링크·버튼·각 위젯이 맞는 키로 동작하는가?
- 복귀: 모달을 닫은 뒤 작업을 이어갈 위치로 돌아오는가?
- 반복: 열고 닫기를 반복해도 초점이 사라지거나 이벤트가 중복되지 않는가?
- 기록: 검사 환경과 남은 문제를 적었는가? 자동 검사 결과를 수동 과업 검사의 대체로 쓰지 않았는가?
이 확인표는 키보드 경로를 좁혀 보는 도구다. 스크린리더에서의 이름과 상태 전달, 대비, 확대, 오류 안내 등은 별도 검토가 필요하다. AI에게 큰 완성 선언을 받기보다, 사용자가 한 과업을 끝낼 수 있다는 작은 근거를 쌓는 편이 다음 수정도 명확해진다.


