위젯 하나로 접근성이 해결된다는 믿음이 무너졌다
웹사이트 구석에 떠 있는 그 버튼을 한 번쯤 본 적 있을 것이다. 휠체어 아이콘이나 사람 모양 픽토그램이 그려진 플로팅 버튼을 클릭하면, '접근성 프로필' 패널이 펼쳐지며 고대비 모드, 큰 글꼴, 난독증 모드 같은 옵션들이 나타난다. accessiBe, UserWay, AudioEye 같은 벤더들이 판매하는 접근성 오버레이 위젯이다. 이들의 공통된 약속은 하나였다—JavaScript 파일 하나를 사이트에 심으면 ADA/WCAG 준수가 자동으로 이뤄진다.
2025년 1월, 미국 FTC가 이 약속에 100만 달러짜리 제재를 내렸다. accessiBe가 자사 위젯으로 사이트를 '완전한 ADA 준수' 상태로 만들 수 있다고 마케팅했지만, 자체 내부 데이터조차 스크린 리더 사용자들이 위젯이 설치된 사이트에서 심각한 문제를 겪었다는 사실을 보여주고 있었다. dev.to에 공개된 분석 글이 이 사태를 정리하며 던진 질문은 간결하다—왜 오버레이는 작동하지 않는가.
런타임 패치가 구조적 결함을 고칠 수 없는 이유
오버레이의 작동 방식 자체가 근본적 한계를 내포한다. 위젯은 브라우저에서 DOM을 런타임에 스캔하고 빠진 ARIA 속성을 덧붙이는 방식으로 동작한다. <div>에 click 핸들러를 달고 role="button"을 주입해도, 그 요소는 키보드 탭 순서에 들어오지 않고 포커스 상태도 없으며 활성화 시 아무것도 알리지 않는다. 구조가 틀렸으면 라벨을 아무리 붙여봐야 접근성이 생기지 않는다.
더 심각한 문제는 역효과다. 2021년 Deque 사용자 연구에 따르면 스크린 리더 사용자들은 오버레이가 주입한 ARIA와 씨름하는 데 사용 시간의 60~80%를 소비했다. 많은 AT 사용자들이 사이트에 접속하자마자 오버레이를 비활성화하는 것을 첫 번째 습관으로 삼고 있을 정도다. Berkeley/Princeton의 2023년 연구(Wagner et al.)도 같은 결론을 내렸다—오버레이는 어떠한 측정 가능한 지표에서도 접근성을 개선하지 못했고, 일부 경우에는 오히려 탐색을 더 어렵게 만들었다.
규제 프레임워크도 이 점을 명확히 한다. EN 301 549(EAA 2025가 참조하는 표준)는 서버가 반환하는 HTML을 기준으로 준수 여부를 평가한다. JavaScript가 런타임에 무엇을 바꾸든, AT가 스크립트 실행 전에 페이지를 파싱하거나 JavaScript를 비활성화한 환경에서는 그 변경이 존재하지 않는 것과 같다. 컴플라이언스 논거가 JavaScript의 올바른 실행을 전제한다면, 그것은 컴플라이언스 논거가 아니다.
진짜 접근성은 HTML 구조에서 시작하고 CI로 지속된다
접근성 오버레이를 걷어낸 자리에 필요한 것은 사실 새로운 도구가 아니다. 소스 HTML을 올바르게 고치고, 그 상태를 CI에서 회귀 없이 유지하는 것—이게 전부다. npx axe-core/cli로 실제 서빙되는 HTML을 스캔하고, 심각한 이슈를 PR마다 자동으로 차단하는 파이프라인을 세운다. WCAG 기준 중 자동화 도구가 커버하는 ~57%는 이 방식으로 잡힌다. 나머지 ~43%는 연간 한 번의 인간 감사로 보완한다. 비용은 $5~15K 수준—월 $5K짜리 오버레이 구독보다 훨씬 저렴하고, 실제로 작동한다.
오버레이를 'TLS'를 프라이버시 정책에 적어두고 실제로는 HTTPS를 제공하지 않는 것과 같다고 비유한 표현이 정확하다. 라벨과 실질은 다른 것이고, 규제는 실질을 본다.
현대 CSS가 '구조 기반 접근성'을 더 쉽게 만든다
여기서 한 발 더 나아갈 수 있다. 접근성을 구조 기반으로 설계한다는 철학은, 최근 CSS에 추가되고 있는 신기능들과 정확히 같은 방향을 가리킨다.
CSS Anchor Positioning을 생각해보자. 툴팁이나 팝오버를 특정 요소에 붙이기 위해 우리는 오랫동안 getBoundingClientRect()를 호출하고 Popper.js 같은 라이브러리를 의존성으로 달았다. 스크롤이나 레이아웃 변화에 반응하는 50줄의 JavaScript 로직이 필요했다. Anchor Positioning은 이 문제를 선언적 CSS로 해결한다—anchor-name으로 기준 요소를 지정하고, 팝오버에 position-anchor를 연결하면 브라우저가 뷰포트 경계 처리와 위치 계산을 전담한다. 포커스 관리와 키보드 네비게이션이 올바른 HTML 구조(<button>, popover 속성)에서 자연스럽게 따라온다. JS 레이어가 줄어든 만큼 AT가 해석할 수 있는 구조가 남는다.
field-sizing: content도 마찬가지다. textarea가 입력 내용에 따라 자동으로 높이를 조정하도록 scrollHeight를 읽고 style.height를 수동으로 업데이트하는 이벤트 리스너를 달아본 경험은 누구에게나 있다. 이 CSS 한 줄이 그 전체를 대체한다. JavaScript로 레이아웃을 제어할 때 발생하는 타이밍 이슈나 포커스 상태 불일치가 사라진다. min-height: 3lh로 최소 표시 크기를 의미 단위로 지정하고, max-height로 무한 팽창을 방지하는 것이 권장 패턴이다.
두 기능의 공통점은 명확하다—JavaScript가 담당하던 레이아웃 계산을 브라우저 렌더링 엔진으로 내려보냄으로써, DOM 구조가 더 단순하고 시맨틱하게 유지된다. AT가 파싱하기 쉬운 구조, 키보드 탐색이 자연스러운 탭 순서, 예측 가능한 포커스 흐름은 이런 설계적 선택의 부산물로 얻어진다.
접근성은 '품질의 증거'다
FTC 제재가 보내는 신호를 프로덕트 관점에서 읽으면 이렇다—접근성은 이제 법무팀이 체크하는 컴플라이언스 박스가 아니라, 제품의 기술적 품질을 직접 드러내는 지표다. 오버레이 위젯은 그 품질 문제를 감추려는 시도였고, 규제는 그 감추기가 통하지 않는다고 선언했다.
시맨틱 HTML, 올바른 레이블, 실제로 작동하는 포커스 상태, 키보드 탐색—이것들은 화려하지 않다. 하지만 현대 CSS 신기능들이 JavaScript 의존성을 걷어내는 방향으로 진화하고 있는 지금, 접근성을 구조에서 설계하는 비용은 계속 낮아지고 있다. 일회성 리팩터링과 CI 파이프라인 한 줄로 규제 심사를 통과하는 수준까지 도달할 수 있다면—오버레이 구독료를 쓸 이유가 없다.
런타임에 패치하는 것과 처음부터 올바르게 짜는 것의 차이. 프론트엔드 품질의 본질은 항상 거기에 있었다.