aria-label과 텍스트 콘텐츠

Frontend

aria-label을 쓰다 보면 헷갈리는 부분이 있다. 텍스트 콘텐츠와 aria-label을 함께 넣었을 때, 스크린 리더가 둘 다 읽을지 아니면 하나만 읽을지 애매한 것이다.

 

예를 들어 버튼에 "삭제"라고 써있고 aria-label="이 리뷰 삭제하기"를 추가하면 "이 리뷰 삭제하기 삭제"로 읽힐까? 아니면 둘 중 하나만 읽힐까?

 

정답은 요소마다 다르다. 어떤 요소는 aria-label이 텍스트를 완전히 대체하고, 어떤 요소는 텍스트와 함께 읽힌다.

aria-label이 텍스트를 대체하는 요소들

상호작용하는 요소들

버튼, 링크, 입력 필드처럼 사용자가 클릭하거나 입력하는 요소들은 aria-label이 기존 텍스트를 대체한다.

<button aria-label="이 리뷰 삭제하기">삭제</button>
<!-- 읽힘: "이 리뷰 삭제하기" -->

<a href="/edit" aria-label="프로필 수정 페이지로 이동">수정</a>
<!-- 읽힘: "프로필 수정 페이지로 이동" -->

여기에 해당하는 요소: <a>, <button>, <input>, <select>, <textarea>

 

페이지 구조 요소들

헤더, 네비게이션, 섹션 같은 구조를 나타내는 요소들도 마찬가지다.

<nav aria-label="메인 네비게이션">
  <ul>...</ul>
</nav>
<!-- 읽힘: "메인 네비게이션" -->

여기에 해당하는 요소: <header>, <nav>, <main>, <footer>, <aside>, <section>, <form>, <fieldset>, <legend>, <iframe>, <img>

 

이런 요소들은 "무엇을 하는가"가 중요하기 때문에 aria-label로 더 구체적인 설명을 제공하면 기존 텍스트는 무시된다.

 

aria-label과 텍스트가 함께 읽히는 요소들

반면 제목이나 문단처럼 콘텐츠를 담는 요소들은 다르게 동작한다.

<h2 aria-label="중요 공지:">새로운 기능 안내</h2>
<!-- 읽힘: "중요 공지: 새로운 기능 안내" -->

<p aria-label="참고:">이 기능은 베타 버전입니다.</p>
<!-- 읽힘: "참고: 이 기능은 베타 버전입니다." -->

여기에 해당하는 요소: <h1>~<h6>, <p>, <li>, <dt>, <dd>, <span>, <div> (role이 없을 때)

 

이런 요소들은 "무엇을 담고 있는가"가 중요하다. 콘텐츠 자체가 의미이기 때문에 aria-label은 추가 정보로만 작용한다.

 

실제 사용 예시

아이콘만 있는 버튼

<button aria-label="메뉴 열기">
  <svg>...</svg>
</button>

아이콘만 있고 텍스트가 없는 버튼에서 유용하다.

 

맥락을 추가해야 하는 링크

페이지에 "삭제" 링크가 여러 개 있으면 스크린 리더 사용자는 어떤 걸 삭제하는지 구분하기 어렵다.

<a href="/delete" aria-label="댓글 삭제">삭제</a>

이렇게 하면 "댓글 삭제"로 읽혀서 명확해진다.

 

제목에 강조 추가

<h2 aria-label="필독:">공지사항</h2>
<!-- 읽힘: "필독: 공지사항" -->

제목에 추가 맥락을 넣고 싶을 때 사용할 수 있다.

 

주의해야 할 점

우선순위

aria-labelledby와 aria-label을 함께 쓰면 aria-labelledby가 우선된다.

<button aria-label="무시됨" aria-labelledby="label-id">버튼</button>
<span id="label-id">실제로 읽힘</span>

 

img 태그의 특수성

img 태그는 alt 속성이 있으면 aria-label을 무시한다.

<img src="..." alt="사용됨" aria-label="무시됨">
<img src="..." aria-label="사용됨">

 

다국어 지원

aria-label도 번역해야 한다는 걸 잊지 말자.

<!-- 한국어 -->
<button aria-label="메뉴 열기">
  <svg>...</svg>
</button>

<!-- 영어 -->
<button aria-label="Open menu">
  <svg>...</svg>
</button>

 

지원하지 않는 요소

<strong>, <em>, <code> 같은 요소들은 기본적으로 aria-label을 지원하지 않는다. role을 추가하면 사용할 수 있긴 하다.

 

다음 역할들도 aria-label을 지원하지 않는다: code, caption, deletion, emphasis, generic, insertion, mark, paragraph, presentation/none, strong, subscript, superscript, suggestion, term, time

 

자주 하는 실수

불필요한 중복

<!-- ❌ -->
<button aria-label="제출 버튼">제출</button>
<!-- 읽힘: "제출 버튼" -->

<!-- ✅ -->
<button>제출</button>
<!-- 읽힘: "제출, 버튼" -->

버튼은 이미 역할로 "버튼"이라고 알려주는데 또 말할 필요가 없다.

 

너무 긴 설명

aria-label은 짧고 명확해야 한다. 긴 설명이 필요하면 aria-describedby를 쓰는 게 낫다.

<!-- ❌ -->
<button aria-label="이 버튼을 클릭하면 현재 작성 중인 내용이 모두 삭제됩니다. 삭제된 내용은 복구할 수 없으니 주의하세요.">
  삭제
</button>

<!-- ✅ -->
<button aria-label="삭제" aria-describedby="delete-desc">
  삭제
</button>
<div id="delete-desc" class="sr-only">
  삭제된 내용은 복구할 수 없습니다.
</div>

 

테스트 방법

브라우저와 스크린 리더마다 동작이 조금씩 다를 수 있다. 실제로 테스트해보는 게 제일 확실하다.

  • Windows: NVDA (무료) 또는 JAWS
  • macOS: VoiceOver (내장)
  • 브라우저 확장: 스크린 리더 시뮬레이터

 

처음엔 복잡해 보이지만 핵심은 간단하다. 상호작용 요소는 대체, 콘텐츠 요소는 추가. 이것만 기억하면 대부분의 상황에서 제대로 쓸 수 있다.

'Frontend' 카테고리의 다른 글

Zustand로 전역 상태 관리하기  (0) 2025.11.18
웹 애플리케이션의 렌더링 방식과 Next.js  (0) 2025.11.08
타입스크립트 유틸리티 타입  (0) 2025.11.05
타입스크립트 타입 시스템: 계층과 호환성  (0) 2025.10.31
타입스크립트의 동작 원리  (0) 2025.10.27
'Frontend' 카테고리의 다른 글
  • Zustand로 전역 상태 관리하기
  • 웹 애플리케이션의 렌더링 방식과 Next.js
  • 타입스크립트 유틸리티 타입
  • 타입스크립트 타입 시스템: 계층과 호환성
고견
고견
개발 자국 남기기
  • 고견
    개발자국
    고견
  • 전체
    오늘
    어제
    • 분류 전체보기 (157) N
      • Frontend (29)
        • Next.js (16)
        • JavaScript (7)
      • CS (19) N
        • 자료구조 (9)
        • 알고리즘 (5)
        • 운영체제 (4) N
        • 네트워크 (1) N
      • TIL (93)
      • Dev Log (16)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    함수 타입
    C
    Next.js
    타입 좁히기
    react
    useState
    문자열
    emotion diary
    앱 라우터
    typescript
    트러블 슈팅
    배열
    Trouble Shooting
    memory
    CS
    ai 감성 일기장
    Spa
    바닐라 자바스크립트
    javascript
    자료구조
    App Router
    제네릭
    클래스
    페이지 라우터
    algorithm
    인터페이스
    cs50
    알고리즘
    generic
    Pages Router
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
고견
aria-label과 텍스트 콘텐츠
상단으로

티스토리툴바