AI는 코드를 짜지만, 스크린 리더는 사람이 쓴다
요즘 프로덕션 코드에서 이런 패턴을 자주 마주친다. 버튼처럼 생긴 <div>에 aria-label이 붙어 있고, 아이콘 버튼엔 아무 레이블도 없고, aria-labelledby가 가리키는 ID는 HTML 어딘가에 존재하지 않는다. 새로 작성된 코드임에도 접근성은 오히려 퇴보해 있다. AI 코딩 도구가 일상이 된 지금, 이런 오류가 더 빠르게, 더 자신감 있게 배포되고 있다는 게 문제다.
dev.to에 올라온 Priya Nair의 프로덕션 코드 감사 경험담은 꽤 직접적이다. 수백 개의 코드베이스를 리뷰한 결과, ARIA 사용 사례의 약 70%가 불필요하거나 잘못 구현되어 있었다고 말한다. 그리고 그 결론은 단호하다: "No ARIA is better than bad ARIA." 잘못된 ARIA는 스크린 리더 사용자에게 '저하된 경험'이 아니라 '혼란스러운 경험'을 준다. 이 둘은 완전히 다르다.
반복되는 오류, 패턴은 놀랍도록 일관적이다
가장 흔한 실수는 예상보다 기초적이다. 하나씩 짚어보자.
<div>에 aria-label 붙이기 — 가장 빈번한 오류다. <button> 대신 스타일링이 편한 <div>를 쓰고 ARIA로 접근성을 '때운다'. 하지만 <div>는 키보드 포커스를 받지 못하고, 스크린 리더가 버튼으로 인식하지도 않는다. ARIA는 시맨틱 HTML의 대체재가 아니라 보완재다.
아이콘 전용 버튼에 레이블 없음 — 햄버거 메뉴, 닫기 버튼, 검색 아이콘. 시각적으로는 명확해 보이지만 스크린 리더는 그냥 "버튼"이라고 읽는다. 어떤 버튼인지 알 방법이 없다. aria-label="Close dialog"처럼 동작을 설명하는 레이블이 반드시 필요하다.
존재하지 않는 ID를 향한 aria-labelledby — 에러 메시지도 없고, 콘솔 경고도 없다. 그냥 조용히 접근성이 깨진다. Chrome DevTools의 Accessibility 패널이 잡아주지 않으면 배포 전까지 아무도 모른다.
role="button" + 키보드 핸들러 없음 — tabindex="0"도 없고, keydown 이벤트도 없다. 스크린 리더엔 버튼처럼 들리지만 키보드 사용자는 탭으로 접근조차 못 한다. '접근성을 고려한 것처럼 보이지만 절반만 구현된' 가장 위험한 패턴이다.
AI가 이 오류를 더 잘 만드는 이유
AI 코딩 도구는 '그럴듯한 코드'를 매우 빠르게 생성한다. 문제는 접근성이 기능적으로 작동하는 것처럼 보이지만 실제로는 깨져 있는 케이스를 만들어내는 데 특히 취약하다는 점이다. AI는 시각적 렌더링을 기준으로 학습하지, 스크린 리더의 읽기 흐름을 기준으로 학습하지 않는다. <div class="btn" onclick="...">Submit</div>는 브라우저에서 완벽하게 작동하고, AI 입장에서도 '버튼처럼 보이는 코드'를 생성한 것이다. 하지만 VoiceOver를 켜는 순간, 그건 버튼이 아니다.
더 심각한 건 AI가 생성한 코드에 aria-label이 붙어 있을 때다. 개발자는 "ARIA까지 챙겼네"라며 안심하고 머지한다. 실제론 존재하지 않는 ID를 참조하거나, 가시 텍스트를 그대로 중복한 채로. 보이는 것과 실제 접근성은 다르다는 사실을 AI는 아직 충분히 내면화하지 못했다.
'검증 없는 완료'가 접근성을 죽인다
최근 geek news에서 소개된 leceipts 프로젝트가 흥미로운 각도를 제공한다. AI 코딩 도구의 고질적 패턴—"수정했습니다"라고 말하지만 실제로는 여전히 깨져 있는—을 태도가 아닌 프로세스로 해결하려는 시도다. 핵심은 단순하다: 변경마다 어떻게 검증했고 결과가 어땠는지를 구조적으로 기록하게 강제한다.
접근성 맥락에서 이 접근은 훨씬 직접적인 의미를 갖는다. 접근성 버그는 시각적으로 드러나지 않는다. 기능 버그와 달리 QA 단계에서 걸리지 않고, 사용자 리포트도 잘 오지 않는다. 스크린 리더를 직접 켜거나, Axe 같은 자동화 도구를 CI에 끼워 넣지 않으면 깨진 채로 배포된다. "동작한다"와 "접근 가능하다"는 완전히 다른 기준이다. Done의 정의에 접근성 검증이 포함되어야 한다.
실무에서 바로 적용할 수 있는 세 가지 기준
AI가 짠 코드를 리뷰할 때, 접근성 관점에서 최소한 이 세 가지를 확인하자.
-
시맨틱 HTML이 먼저인가 —
<button>,<a>,<input>,<label>등 네이티브 요소를 쓰고 있다면 ARIA는 대부분 불필요하다. 커스텀 요소나<div>기반 컴포넌트가 보이면 바로 의심하라. -
아이콘 전용 인터랙티브 요소에 텍스트 대안이 있는가 —
aria-label,aria-labelledby, 또는 시각적으로 숨긴 텍스트(sr-only클래스) 중 하나는 반드시 있어야 한다. -
CI에 접근성 린터가 붙어 있는가 — Axe-core, eslint-plugin-jsx-a11y 중 하나라도 파이프라인에 없다면, 지금 추가할 좋은 타이밍이다. AI가 생성한 컴포넌트가 늘수록 자동화 검증의 가치는 비례해서 올라간다.
앞으로: 접근성 책임은 도구가 아니라 개발자에게 있다
AI 코딩 도구가 접근성을 점점 더 잘 이해하게 될 거라는 전망은 틀리지 않다. 하지만 지금 이 순간, AI는 WCAG 2.1의 규칙을 암기하고 있을지언정 스크린 리더 사용자의 실제 맥락을 이해하지는 못한다. 코드가 빠르게 생성될수록, 검증은 느리게 따라오고 있다.
접근성은 배포 직전 체크리스트가 아니다. 컴포넌트 설계 단계에서, 코드 리뷰 기준에서, CI 파이프라인에서 동시에 작동해야 하는 시스템이다. AI가 코드를 짜는 시대일수록, 그 시스템을 설계하고 유지하는 책임은 더 명확하게 개발자에게 남는다. 스크린 리더를 쓰는 사용자는 AI가 "수정했습니다"라고 말했는지 모른다. 그들은 그냥 탭 키를 누를 뿐이다.