UX
웹 접근성 테스트에서 발견한 아이콘 버튼의 이름 누락과 수정 기준
화면에는 보이지만 스크린 리더가 읽지 못하던 아이콘 버튼을 직접 테스트하며 aria-label과 구조를 정리했습니다.
눈으로는 정상인데 테스트는 실패했다
모바일 헤더의 검색과 메뉴 버튼을 SVG 아이콘만 넣어 만들었다. 마우스로는 잘 눌렸지만 접근성 점검에서 버튼에 이름이 없다는 결과가 나왔다. 처음에는 아이콘 파일에 title을 추가하면 해결될 것이라고 생각했는데, 버튼 자체의 accessible name은 여전히 비어 있었다.
실제 확인은 키보드만 사용해 탭을 이동하고, 브라우저 접근성 트리에서 버튼 이름을 읽는 방식으로 했다. 아이콘 모양을 설명하는 것이 아니라 사용자가 수행할 동작을 이름으로 줘야 한다는 점이 헷갈린 지점이었다.
버튼과 장식의 역할을 분리했다
검색 버튼은 다음처럼 버튼에 직접 이름을 주고, SVG는 장식으로 표시했다.
<button type="button" aria-label="검색 열기" onClick={openSearch}>
<SearchIcon aria-hidden="true" />
</button>
메뉴가 열렸을 때는 이름도 상태에 맞게 바꿨다.
<button
type="button"
aria-expanded={isOpen}
aria-controls="mobile-navigation"
aria-label={isOpen ? '메뉴 닫기' : '메뉴 열기'}
onClick={() => setIsOpen(value => !value)}
>
<MenuIcon aria-hidden="true" />
</button>
처음에는 title="menu"를 SVG에 넣었지만, 언어가 섞이고 버튼의 현재 상태가 전달되지 않았다. 텍스트가 화면에 보이지 않는다는 이유로 aria-label을 모든 곳에 붙이는 것도 피했다. 이미 읽을 수 있는 텍스트가 있는 버튼에는 중복 이름이 생길 수 있기 때문이다.
수정 뒤에 직접 확인한 항목
- 키보드 Tab 순서가 시각적 순서와 크게 어긋나지 않는가
- 포커스 표시가 배경 위에서 보이는가
- 아이콘-only 버튼에 동작 중심의 이름이 있는가
- 열림/닫힘 상태가
aria-expanded로 전달되는가 - 닫힌 메뉴가 키보드 포커스를 계속 받을 수 있지 않은가
- SVG 장식이 버튼 이름을 중복해서 읽게 만들지 않는가
자동 테스트는 누락을 빨리 알려줬지만, 포커스가 어디로 이동하는지까지 대신 판단해주지는 않았다. 특히 메뉴를 닫은 뒤 메뉴 안의 첫 링크에 포커스가 남지 않는지도 브라우저에서 확인했다.
작은 UI일수록 이름을 먼저 정한다
이번 수정은 코드 몇 줄이었지만, 버튼을 “아이콘이 있는 사각형”으로 만들지 않고 “검색을 여는 컨트롤”로 정의하는 데서 시작했다. 디자인이 끝난 뒤 접근성을 덧붙이는 대신, 컴포넌트 props에 label과 상태를 먼저 넣는 쪽이 다음 화면에서도 실수를 줄이는 기준이 됐다.