잃어버린 접근성을 찾아서
Source: Woowahan Tech
개발한 서비스의 접근성을 직접 확인해 보신 적 있나요? 바쁜 일정 속에 각종 요구사항을 반영하다 보면, 접근성은 흔히 ‘언젠가 챙겨야 할 착한 일’ 정도로 치부되곤 합니다. 부끄럽지만 저희도 마찬가지였습니다.
그러나 접근성을 소홀히 하면 실제 사용 과정에서 예상보다 큰 불편이 생길 수 있습니다. 예를 들어 상품을 구매하고자 화면을 수백 번 터치해야 한다면, 과연 그 서비스를 정상적인 서비스라고 부를 수 있을까요?
웹의 창시자 **팀 버너스 리(Tim Berners‑Lee)**는 이렇게 말했습니다.
“웹의 힘은 보편성에 있습니다. 장애에 상관없이 모두가 접근할 수 있다는 것이 가장 중요한 부분입니다.”
보편성을 지키지 못한다면 우리 서비스는 누군가에게 아예 사용 불가능한 무용지물이나 다름없습니다.
이 글은 접근성 준수라는 숙제를 하려다 ‘사용 불가능한 수준의 사용자 경험’을 마주하고 이를 뜯어고친 치열한 개선기입니다. 웹 접근성의 영역은 넓고 방대하지만 이번 작업에서는 스크린 리더 사용자들의 경험에 집중했습니다. 스크린 리더의 실제 발화를 기준으로 상품 상세 페이지의 접근성을 어떻게 개선했는지 소개하겠습니다.
스크린 리더란?
Android의 TalkBack, iOS의 VoiceOver 등 접근성 지원 도구이며, 좌우 스와이프로 요소를 하나씩 탐색하며 음성으로 읽어줍니다.
참고: 이 글의 스크린 리더 발화 예시는 iOS VoiceOver를 기준으로 작성되었습니다.
구매하기 버튼까지 300번 이상 스와이프했습니다
Lighthouse를 이용해 측정한 상품 상세 페이지의 접근성 점수는 60~70점으로 좋은 점수는 아니었지만, 버튼에 aria-label을 추가하거나 이미지에 alt 속성을 넣는 등 널리 알려진 방법만으로도 90점 이상의 점수를 받을 수 있었습니다. 하지만 실제로도 개선된 걸까요?
Lighthouse란?
구글에서 개발한 웹 페이지 품질 측정 자동화 도구입니다. 성능(Performance), 접근성(Accessibility), SEO 등 5가지 핵심 영역을 점검하여 0~100점의 점수로 환산해 줍니다.
눈을 가리고 스크린 리더만을 사용해서 상품을 구매해 보겠습니다.
두둥!

휴대기기에서 스크린 리더로 테스트해 본 결과는 충격적이었습니다.
- 기기마다 사소한 차이는 있었지만, 사용자 흐름의 종점이 되는 구매하기 버튼까지 300번 이상의 스와이프 동작이 필요했습니다.
- 탐색 도중 궁금하지 않은 내용이 있어도 스와이프하며 꼭 지나가야 했고, 이는 상당한 피로감을 유발했습니다.
- 한 번에 읽혀야 할 텍스트가 분리되어 읽혔습니다. “990원”이 아니라 “990”과 “원”으로 나뉘어 읽히면 추가 스와이프가 필요하고 맥락 파악이 어려워집니다.
- 버튼을 읽을 때 역할이 불분명했습니다. 예를 들어 “배달팁 자세히 보기” 버튼이 단순히 “버튼”이라고만 읽혀 어떤 동작을 하는지 알 수 없었습니다.
문제 정리
- 피로한 탐색: 모든 요소를 탐색해야 해서 시간이 오래 걸림
- 파편화된 발화: 함께 읽혀야 할 텍스트가 따로 읽혀 맥락 파악이 어려움
- 모호한 역할: 버튼에 역할이 명시되지 않아 어떤 동작인지 알 수 없음
공통으로 시각을 활용한 탐색과 스크린 리더를 통한 탐색 경험에 큰 차이가 발생한다는 문제가 있었습니다. 이를 해결하기 위한 여정을 떠나봅시다.
접근성을 되찾는 여정
1. 탐색 단위 만들기: 랜드마크와 머리말
스크린 리더에는 강력한 탐색 기능이 있습니다. iOS VoiceOver는 로터(Rotor), Android TalkBack은 단위 탐색 기능으로 랜드마크와 머리말 단위로 빠르게 이동할 수 있습니다.
랜드마크란?
페이지의 주요 영역(헤더, 메인, 내비게이션, 푸터, 섹션 등)을 표시합니다. 랜드마크를 사용하면 스크린 리더 사용자가 원하는 영역을 빠르게 탐색할 수 있게 해주는 일종의 ‘페이지 내 지도’ 역할을 합니다.
우리 페이지에는 적절한 랜드마크와 머리말 구조가 없어서 사용자는 오직 순차 탐색만 가능했습니다. 책에서 목차 없이 첫 페이지부터 한 줄씩 읽어야 하는 것과 같습니다.
이를 해결하기 위해 페이지를 의미 있는 섹션으로 나누고, 각 섹션에 명확한 머리말을 배치했습니다.

목록 요소를 사용할 때 주의할 점
VoiceOver에서는 list-style: none이 설정된 요소를 목록으로 인식하지 않기 때문에, CSS로 목록 마커를 제거했다면 role="list"를 명시해야 합니다.
이제 스크린 리더 사용자는 “다른 사람들이 함께 본 상품”, “혜택” 등 머리말 또는 랜드마크 단위로 주요 영역을 빠르게 이동할 수 있습니다.

이런 구조를 페이지 전체에 일관되게 적용하기 위해 재사용 가능한 컴포넌트를 만들어 활용하고 있습니다. section + heading + aria-labelledby 조합을 매번 반복해서 작성할 필요 없이, 컴포넌트가 자동으로 처리해 줍니다.

2. 파편화된 텍스트 통합하기
판매가 “990원”이 스크린 리더에서는 “990”과 “원”으로 따로 읽혔습니다. 그 외에도 많은 텍스트가 파편화되어 탐색을 위해 불필요한 스와이프 동작이 필요했습니다.

템플릿 리터럴 활용
템플릿 리터럴을 사용해 데이터 정보를 하나의 문자열로 표현하면 스크린 리더가 자연스럽게 읽을 수 있습니다.

스타일링 때문에 텍스트를 분리해야 하는 경우, 시각적으로 보이지 않는 요소를 활용했습니다.

이제 스크린 리더가 텍스트를 분리해서 읽지 않아, 불필요한 스와이프가 줄고 내용 파악이 쉬워졌습니다.
왜 span에 aria-label을 사용하지 않았나요?
span이나 div 같은 일반 컨테이너에 aria-label을 사용하면 Android TalkBack에서는 정상 작동하지만 iOS VoiceOver에서는 무시됩니다. aria-label은 버튼, 링크, 랜드마크, 이미지 등 대화형 요소에서만 지원되기 때문입니다. 다양한 환경에서 일관된 경험을 제공하기 위해 NoScreen 컴포넌트와 aria-hidden을 조합한 방법을 선택했습니다.
3. 상호작용 요소의 역할 명확히 하기
상품 상세 페이지 내 많은 버튼이 “버튼”이라고만 읽히거나, 맥락 없이 “전체 보기”, “자세히”로만 읽혔습니다. 무엇을 전체 보기 하는지, 무엇을 자세히 보는지 설명을 추가하여 명확한 맥락을 제공했습니다.

토글 버튼도 문제였습니다. 스크린 리더가 찜하기 버튼의 현재 상태를 알 수 없었습니다. aria-pressed를 사용해 토글 상태를 전달했습니다.

모달이나 바텀시트를 여는 버튼도 클릭 시 무슨 일이 일어날지 예측하기 어려웠습니다. aria-haspopup와 aria-expanded로 상태를 알렸습니다.

마침내 스크린 리더 발화만으로 버튼의 역할과 동작을 알 수 있게 되었습니다.
다시 찾은 접근성
개선 작업 후 가장 극적인 변화는 탐색 횟수였습니다. 구매하기 버튼 도달까지 필요한 스와이프가 20회 미만으로 줄어들었습니다. 기존 대비 90% 이상의 개선이었습니다. 텍스트 발화와 상호작용 요소도 개선하면서 스크린 리더를 통한 탐색 경험이 시각적 탐색 경험과 한층 가까워졌습니다.
개발자를 위한 접근성
접근성 개선 작업은 스크린 리더 사용자를 위해 시작했습니다. 하지만 작업을 하고 나니 개발자에게도 다양한 이점이 있었습니다.
-
시맨틱 태그를 사용하니 코드를 읽는 것만으로 구조를 이해하기 쉬워졌습니다. 태그 이름이 곧 요소의 역할과 의미를 정의합니다.

-
실제 사용자가 요소를 탐색하는 과정과 동일한 흐름으로 테스트할 수 있게 되었습니다. 기존의
className이나data-testid같은 선택자는 사용자의 경험과 거리가 멀었지만, 이를role기반으로 변경하면 더 의미 있는 테스트 코드를 작성할 수 있었습니다.

마치며
접근성 개선, 어렵게 느껴지시나요?
저희도 처음엔 막연하고 어려운 일이라고 생각했습니다. 하지만 막상 시작해 보니 생각보다 어렵지 않았고, 몰랐던 지식을 많이 배웠습니다.
가장 인상 깊었던 것은 Lighthouse 점수를 맹신하면 안 된다는 점이었습니다. 점수가 높아도 실제로는 스크린 리더로 탐색하기 매우 어려울 수 있다는 걸 체험하고 나서야 깨달았습니다. 수백 번 스와이프를 직접 해보는 것만큼 문제의 심각성을 체감하게 해주는 건 없었습니다.
이번 작업을 통해 배운 내용은 가이드 문서로 정리했습니다.
- 시맨틱 태그 사용 가이드
- ARIA 속성 적용 패턴
- 코드 리뷰 시 접근성 체크리스트
- 재사용 가능한 접근성 컴포넌트 예시
접근성을 찾는 여정은 여기서 끝이 아닙니다. 이번 경험을 바탕으로 다른 페이지에도 접근성 개선 작업을 확장할 예정이며, 효율적인 개발을 위한 접근성 테스트 자동화도 검토 중입니다. 새로운 컴포넌트를 생성할 때부터 접근성을 고려하도록 AI용 접근성 rule도 작성 중입니다.
이 글을 읽으신 여러분도 오늘 잠시 시간을 내어 휴대전화의 스크린 리더를 켜보세요. 익숙한 화면이 낯설게 느껴지는 순간, 다양한 문제들을 발견하게 되고, 모두를 위한 웹을 만드는 첫걸음이 시작됩니다.
저희의 고민이 여러분의 접근성 개선 여정에 작은 도움이 되기를 바랍니다.