토스 A11y Fundamentals - 접근성
0. 웹 접근성
올해 8월에 런칭된 토스의 A11y Fundamentals.
“접근성은 어렵다”는 인식을 낮추고 실무에서 바로 적용할 핵심 규칙과 흔한 실수를 명쾌하게 정리해준다.
특히 버튼 안에 버튼을 넣지 않기, 이름 없는 인터랙티브 요소 금지, 역할과 동작의 일치, 시각 정보 보완 같은 원칙이 실 예시와 함께 제시되어 있어, 코드 리팩토링에 바로 활용할 수도 있었다.
1. 접근성의 출발점: 네 가지 축
토스 문서는 접근성 실천을 다음 축으로 안내한다.
- 올바른 구조: HTML을 시맨틱하게, 중첩/감싸기 규칙을 지켜 구성한다.
- 의미 전달: 모든 인터랙티브 요소에 “이름(Accessible Name)”을 제공한다.
- 예측 가능한 동작: 겉모습과 역할/동작이 일치하도록 구현한다.
- 시각 정보 보완: 색·아이콘만으로 의미를 전달하지 않고 대체 수단을 둔다.
2. 올바른 구조 만들기
2-1. 버튼 안에 버튼 넣지 않기
버튼 내부에 또 다른 버튼을 넣으면 포커스 순서, 이벤트 버블링, 스크린 리더 역할 식별이 꼬인다. 의도한 인터랙션을 안전하게 분리해 형제 요소로 두고, 필요한 경우 그룹 컨테이너로 묶는다.
2-2. 테이블 행에 직접 onClick 붙이지 않기
<tr> 자체를 클릭 가능하게 만들면 키보드 탐색/포커스 관리가 깨지기 쉽다. 행 전체 클릭이 필요하다면 셀 내부에 명시적 버튼/링크를 제공해 역할을 드러내자.
3. 의미를 정확하게 전달하기 (Accessible Name)
3-1. 인터랙티브 요소에 이름 붙이기
입력, 버튼, 셀렉트 등은 반드시 이름이 있어야 한다. 이름이 없으면 스크린 리더는 목적을 알 수 없고, 자동화 테스트도 불안정해진다. 우선순위는 aria-labelledby → aria-label → <label> → placeholder/콘텐츠 순으로 계산된다.
<!-- 권장: label과 연결 -->
<label for="user-name">이름</label>
<input id="user-name" type="text" />
<!-- 대안: 시각적 레이블이 불가능할 때 -->
<input type="text" aria-label="이름" placeholder="이름을 입력하세요" />
aria-label은 요소의 접근 가능한 이름을 직접 지정한다. 남발은 금물이고, 시각적 레이블이 어려운 경우에만 보완적으로 사용한다.
3-2. 같은 이름의 요소엔 설명 추가
동일한 이름의 버튼/링크가 여러 개라면 추가 설명(aria-describedby 등)으로 구분해 사용자가 맥락을 파악하도록 돕는다. (예: “삭제 – 댓글”, “삭제 – 게시글”)
4. 예측 가능한 인터랙션 만들기
4-1. 버튼의 역할과 동작을 일치
<div onClick>에 CSS로 버튼처럼 보이게만 만드는 건 키보드, 스크린 리더 모두에 비협조적이다. 가능한 <button> 태그를 쓰고, 불가피하다면 role="button", tabindex="0", Enter/Space 키 처리까지 구현한다.
<!-- 가장 좋은 방법 -->
<button onClick={handleSubmit}>제출</button>
<!-- 대안 -->
<div
role="button"
tabIndex={0}
onClick={handleSubmit}
onKeyDown={(e) => (e.key === 'Enter' || e.key === ' ' ) && handleSubmit()}
>
제출
</div>
4-2. 입력은 form으로 감싸기
엔터 제출, 에러 요약, 네이티브 검증 등 웹 플랫폼의 기본 기능을 확보한다. 폼을 벗어난 임의의 키보드 핸들링은 예측 가능성을 떨어뜨린다.
5. 시각 정보에만 의존하지 않기 (대체 텍스트)
5-1. 정보/기능 전달 이미지엔 의미 있는 alt
아이콘 버튼의 이미지는 “검색”, “닫기”처럼 목적을 직설적으로 설명한다. 장식용 이미지는 alt=""로 무시시켜 불필요한 낭독을 막는다.
<!-- 의미 전달: 목적을 설명 -->
<button><img src="search.svg" alt="검색" /></button>
<!-- 장식용: 빈 alt -->
<img src="divider.png" alt="" />
복합 그래픽(여러 조각으로 하나의 이미지를 구성)엔 role="img"와 라벨을 사용해 의미를 한 번에 전달할 수 있다. ([developer.mozilla.org][3])
6. 간단하게 만들어본 체크리스트
- 버튼/링크는 진짜 요소로 구현했는가?
- 모든 인터랙티브 요소에 이름이 있는가?
- 장식 이미지는
alt="", 의미 이미지는 의미 있는 alt를 제공했는가? - 표/리스트/폼은 시맨틱 구조를 지키는가?
- 키보드만으로 모든 흐름을 수행할 수 있는가?
- ARIA는 필요할 때만, 표준 패턴대로 사용했는가?
마치며
접근성은 거창한 기능을 추가하는 일이 아니라, 작은 코드 선택을 올바르게 하는 습관에서 시작된다는 것을 다시 느꼈다. 토스 문서를 통해 시맨틱 태그 사용, 인터랙티브 요소에 이름 붙이기, 키보드 접근성 보장처럼 기본적이지만 놓치기 쉬운 원칙들을 정리할 수 있었다.
앞으로도 화면에 보이는 UI만 만드는 것이 아니라, 누구나 사용할 수 있는 인터페이스인지 계속 점검하며 개발해 나가고자 한다.