아이콘 버튼

아이콘 버튼의 accessible name을 점검하는 실제 순서

텍스트 없는 SVG 아이콘 버튼의 Accessible Name 계산 방식, aria-hidden='true' 및 aria-label 적용 가이드를 다룹니다.

작성자 서호영 (기획·개발·콘텐츠 검토) · 발행 · 수정 · 읽기 8분

아이콘 전용 버튼의 접근 가능한 이름(Accessible Name) 구조텍스트 없이 SVG 아이콘만 있는 버튼은 aria-label이나 sr-only 텍스트를 제공하지 않으면 스크린리더가 이름을 알 수 없습니다.WCAG 2.2 4.1.2 & Accessible Name Computation (AccName)이름 없는 SVG 버튼FAIL (4.1.2)접근성 트리: "버튼" (이름 없음)AccName 계산 결과: 빈 문자열("")aria-label 또는 sr-only 텍스트aria-label="검색"PASS (AA)접근성 트리: "검색, 버튼" 노출내부 SVG는 aria-hidden="true"로 중복 읽기 방지
자체 검증 도식: 아이콘 전용 버튼에는 aria-label="동작 설명"처럼 버튼 자체에 접근 가능한 이름을 제공하거나, 화면에는 보이지 않지만 보조기술에 전달되는 동작 설명 텍스트를 배치할 수 있습니다. 장식용 SVG에는 aria-hidden="true"를 지정하는 방법을 검토하세요.

실무 검증 기록

마크업 및 접근성 트리 대조

본 기록은 공개 fixture와 재현 조건을 기준으로 정리한 기술 설명입니다. 실제 브라우저·스크린리더 조합의 동작은 별도 수동 검토가 필요합니다.

접근성 기술 검증 상세 내역
검증 상태공개 fixture 기반 재현 완료
검증 기준공개 fixture 및 재현 조건
검증 범위SVG 아이콘 단독 버튼의 Accessible Name 계산 검증 및 명시된 입력값에 한정
수동 확인실제 브라우저·키보드·스크린리더 환경에서 별도 확인 필요
fixture에서 확인한 기대 결과[실패 상태] 접근 가능한 이름이 빈 문자열 ➔ [수정 목표] aria-label 또는 sr-only 이름 추가

검증에 사용된 실제 픽스처 / 재현 조건

텍스트 없는 button + SVG + aria-hidden
검증 범위 및 한계
  • SVG 내부에 <title>과 버튼의 aria-label이 동시 존재할 때의 우선순위 브라우저별 미세 차이
  • 다국어 번역 시 sr-only 텍스트 누락 위험

주장과 직결된 W3C 공식 규격

모던 웹 디자인의 UI 컴포넌트 트렌드는 불필요한 텍스트를 덜어내고 직관적인 그래픽 아이콘으로 조작부를 구성하는 경향이 매우 강합니다. 검색을 상징하는 돋보기 아이콘, 쇼핑몰의 장바구니 아이콘, 모바일 내비게이션의 햄버거 메뉴 아이콘, 팝업 창의 닫기(X) 아이콘 등이 대표적인 예입니다. 시력이 정상인 사용자에게는 이 아이콘들이 어떤 기능을 하는지 한눈에 직관적으로 이해되지만, 화면을 볼 수 없는 스크린리더 사용자에게 텍스트가 없는 <button><svg>...</svg></button> 마크업은 암흑과 같습니다. 스크린리더가 해당 버튼에 도달했을 때 들려주는 음성은 단지 '버튼' 또는 SVG 내부의 복잡한 패스(Path) 좌표 문자열뿐입니다. W3C WCAG 2.2 성공 기준 4.1.2(Name, Role, Value)는 모든 인터랙티브 컨트롤이 명확한 '접근 가능한 이름(Accessible Name)'을 가져야 한다고 명시합니다. 이 글에서는 인라인 SVG 아이콘 버튼에 접근 가능한 이름을 부여하는 기술적 표준과 실무 검증 절차를 다룹니다.

텍스트 없는 버튼이 보조공학 엔진에서 처리되는 치명적 과정

웹 브라우저는 버튼 요소를 만났을 때, 내부의 텍스트 노드(Text Node)를 가장 우선적인 접근 가능한 이름으로 채택합니다. 그러나 버튼 내부에 텍스트가 없고 오직 <svg>나 <img> 태그만 들어있다면 브라우저는 극심한 혼선에 빠집니다.

특히 인라인 SVG를 사용할 경우, 브라우저 엔진에 따라 SVG 내부의 <path>, <g> 태그를 접근성 트리에 제멋대로 노출하거나, 아무런 레이블을 찾지 못해 단지 '버튼(Button)'이라고만 낭독합니다. 전자상거래 웹사이트의 상품 상세 페이지에서 '위시리스트 담기 버튼', '장바구니 담기 버튼', '공유하기 버튼'이 모두 스크린리더에게는 '버튼, 버튼, 버튼'으로 연속 낭독되는 촌극이 빚어지는 것입니다. 시각장애인 사용자는 버튼이 3개 있다는 사실만 알 수 있을 뿐, 어느 버튼을 눌러야 결제가 진행되는지 전혀 알 수 없어 구매를 포기하게 됩니다.

접근 가능한 아이콘 버튼을 만드는 3단계 공식 마크업 패턴

W3C WAI-ARIA 명세와 웹 표준을 완벽히 준수하는 아이콘 버튼 제작 순서는 다음 3단계로 정립됩니다.

  • 1단계: 그래픽 요소의 보조공학 차단(aria-hidden='true'): <svg> 태그 자체는 순수한 시각적 장식이므로, <svg aria-hidden='true' focusable='false'> 속성을 선언합니다. focusable='false'는 구형 IE/Edge 브라우저에서 SVG가 불필요하게 탭 포커스를 가져가는 오랜 버그를 차단하는 필수 방어 코드입니다.
  • 2단계: 부모 버튼에 명확한 aria-label 선언: 감싸고 있는 <button> 태그에 aria-label='쇼핑백에 담기' 또는 aria-label='검색창 열기'와 같이 구체적인 동작(Action)과 목적(Purpose)을 나타내는 간결한 문자열을 부여합니다.
  • 3단계: 동적 상태 변화 반영: 만약 해당 버튼이 토글 버튼(예: 찜하기/좋아요)이라면, 좋아요가 선택된 상태에서는 aria-label='위시리스트에서 제거'로 레이블을 바꾸거나 aria-pressed='true' 속성을 함께 동기화해야 합니다.

aria-label vs .sr-only 텍스트 노드: 실무 선택 가이드

현업 개발팀에서 가장 자주 부딪히는 논쟁 중 하나는 'aria-label 속성을 쓸 것인가, 아니면 버튼 내부에 <span class="sr-only">텍스트</span>를 넣을 것인가'입니다. 두 방식 모두 기술적으로 훌륭한 접근 가능한 이름을 생성하지만, 명확한 트레이드오프가 존재합니다.

aria-label 속성은 마크업이 매우 깔끔해지고 유지보수가 편리하다는 강력한 장점이 있습니다. 그러나 구글 번역이나 브라우저 자동 번역 확장 프로그램이 동작할 때, HTML 속성(Attribute) 값인 aria-label은 번역하지 않고 건너뛰는 번역 엔진의 한계가 존재합니다.

반면 <button><svg aria-hidden='true'>...</svg><span class='sr-only'>장바구니 담기</span></button>처럼 시각적 숨김 텍스트 노드를 배치하는 방식은 실제 DOM 텍스트 노드이므로 모든 자동 번역 엔진이 한국어를 영어, 중국어, 일본어로 완벽하게 번역해 줍니다. 따라서 글로벌 다국어 서비스를 운영하는 웹사이트라면 .sr-only 방식을, 단일 언어 서비스나 빠른 컴포넌트 라이브러리 개발이라면 aria-label 방식을 채택하는 것이 가장 현명한 아키텍처 선택입니다.

개발자 도구(Inspect)를 통한 Accessible Name 정밀 검증법

코드를 작성한 뒤에는 반드시 실제 브라우저가 계산한 최종 이름을 확인해야 합니다.

Chrome 개발자 도구에서 아이콘 버튼을 우클릭하고 '검사(Inspect)'를 누른 뒤, 스타일 창 옆에 있는 'Accessibility(접근성)' 탭을 클릭합니다. 'Computed Properties' 항목에 'Name: "장바구니 담기"'가 명확하게 찍혀 있는지, 그리고 해당 이름이 어디서 추출되었는지(From attribute: aria-label) 확인합니다.

만약 Name 항목이 비어 있거나 'Name: ""'로 나타난다면, 스크린리더 사용자에게 이름 없는 유령 버튼으로 전달되고 있다는 명백한 증거이므로 즉시 마크업을 수정해야 합니다.

W3C Accessible Name Computation 1.2 알고리즘의 4단계 연산 우선순위

스크린리더가 아이콘 버튼을 만났을 때 무엇을 읽을지 결정하는 원리는 W3C의 Accessible Name and Description Computation 명세에 엄격히 정의되어 있습니다. 브라우저 접근성 엔진은 다음 4단계 우선순위에 따라 단 하나의 문자열을 계산합니다.

첫째, aria-labelledby 속성이 존재하면 다른 모든 텍스트보다 우선하여 대상 노드의 텍스트를 결합합니다. 둘째, aria-labelledby가 없으면 aria-label 문자열을 채택합니다. 셋째, 네이티브 텍스트 노드 및 대체 텍스트(alt)를 수집합니다. 넷째, 위의 모든 조건이 충족되지 않았을 때 최후의 대체 수단으로 title 속성을 읽습니다.

가장 빈번한 실수는 aria-label과 title을 동시에 선언했을 때 발생합니다. 브라우저는 aria-label을 accessible name으로 확정하고 title은 부가 설명으로 분리하거나 무시하므로 보조공학마다 중복 낭독이나 불일치가 초래됩니다.

  • 1순위: aria-labelledby (참조 대상 ID 노드의 텍스트 결합)
  • 2순위: aria-label (직접 선언된 접근성 이름 문자열)
  • 3순위: 네이티브 텍스트 서브트리 노드 및 img alt 속성
  • 4순위: title 속성 (최후 Fallback, 권장하지 않음)

인라인 SVG 아이콘 버튼에서 발생하는 이름 이중 선언 버그와 방어 코드

디자인 시스템에서 흔히 사용하는 인라인 SVG 버튼에는 종종 개발 도구가 자동 생성한 svg title 태그와 래퍼 버튼의 aria-label이 혼재되어 있습니다.

브라우저 엔진에 따라서는 버튼 요소 자체의 accessible name과 내부 SVG 자식 요소의 accessible name을 별개의 접근성 노드로 인식하여 "검색, 검색, 버튼"과 같이 단어를 두 번 연속 낭독하는 치명적인 사용성 저하가 발생합니다. 버튼 루트에만 이름을 단일 선언하고 내부는 완전히 격리해야 합니다.

  • SVG 내부 격리: 내부 <svg> 요소에 aria-hidden="true"와 focusable="false"를 명시하여 접근성 트리에서 완전 배제
  • 단일 명칭 선언: 대화형 상위 <button> 태그에 aria-label="통합 도서 검색" 형태로 명확한 목적 단일 부여
  • DevTools 검증: Elements 패널 ➔ Accessibility ➔ Computed Properties에서 Name 단일 산출 확인

흔한 마크업 안티패턴과 올바른 예방책

잘못된 마크업 패턴올바른 접근성 구현
<button><svg>...</svg></button> 형태로 작성하고 aria-label 및 내부 대체 텍스트를 완전히 생략하는 것button 요소에 aria-label 속성을 추가하거나 내부 .sr-only span 텍스트를 배치합니다.
SVG 내부 <title> 태그만 작성하고 <button> 자체에는 아무런 접근성 속성을 주지 않는 것SVG title 속성의 스크린리더 호환성 공백을 고려하여 상위 button 요소에 aria-label을 명시합니다.

보조공학 낭독 및 브라우저 파싱 한계

  • 아이콘 버튼의 aria-label에 '검색 버튼'처럼 '버튼' 역할을 중복 기재하면 '검색 버튼, 버튼'으로 중복 낭독됩니다.
  • 버튼 내부 SVG에 aria-hidden="true"를 빠뜨리면 일부 보조기술에서 그래픽 요소를 불필요하게 낭독할 수 있습니다.

주요 공식 상세 규격

규격 검토 기준일 2026-09-06

작성 및 검토 책임 정보

  • 작성자: 서호영
  • 실제 수행 역할: 기획·개발·콘텐츠 검토
  • 최초 작성일:
  • 최종 수정일:
  • 검증 기준: 공개 fixture 및 재현 조건

네이티브 HTML, ARIA 명세, 브라우저 및 스크린리더 조합에 따라 실제 보조공학 동작은 차이가 발생할 수 있습니다. 오류를 발견하셨거나 검증 데이터에 보완이 필요한 경우 오류 제보 및 문의 또는 liebe2460@naver.com로 알려주시면 사실 확인 후 정정합니다.