Cert
UNIT · 1.2

WAI-ARIA 역할·속성·상태

WAI-ARIA Roles, Properties, and States

한국어 해설 KO

Original Text EN

WAI-ARIA의 역할(Roles), 속성(Properties), 상태(States)를 이해하고, ARIA를 언제, 어떻게 사용해야 하는지 학습합니다.

Understand WAI-ARIA Roles, Properties, and States and learn when and how to use ARIA correctly.

Objectives

ARIA의 역할, 속성, 상태의 차이를 설명할 수 있다

ARIA 사용의 첫 번째 규칙을 이해한다

주요 aria-* 속성(aria-label, aria-labelledby, aria-live 등)의 용도를 설명할 수 있다

aria-live 영역의 두 가지 값(polite, assertive)의 차이를 설명할 수 있다

Learning Objectives

Explain the differences between ARIA Roles, Properties, and States

Understand the First Rule of ARIA Use

Describe the purpose of key aria-* attributes

Distinguish between aria-live='polite' and aria-live='assertive'

ARIA란 무엇이고 무엇이 아닌가

What ARIA Is — and Isn't

WAI-ARIA(Accessible Rich Internet Applications)는 시맨틱 HTML만으로 표현하기 어려운 복잡한 UI 패턴(탭, 트리, 콤보박스, 라이브 영역 등)의 의미를 보조기술에 전달하는 W3C 표준입니다. ARIA는 접근성 트리에 노출되는 이름·역할·상태 정보를 바꿉니다.

WAI-ARIA (Accessible Rich Internet Applications) is the W3C standard for conveying the semantics of complex UI patterns — tabs, trees, comboboxes, live regions — that semantic HTML alone cannot express. ARIA changes the name, role, and state information exposed in the accessibility tree.

중요한 한계: ARIA는 의미만 바꿀 뿐 동작을 만들지 않습니다. `role="button"`을 붙여도 키보드 포커스나 Enter/Space 활성화는 생기지 않으며, 개발자가 tabindex와 키 이벤트를 직접 구현해야 합니다. 'ARIA는 약속이다 — 역할을 선언했으면 그 역할답게 동작하게 만들 책임이 따라온다'는 관점이 중요합니다. 잘못 쓴 ARIA는 없느니만 못합니다(No ARIA is better than bad ARIA).

A critical limitation: ARIA changes semantics only — it creates no behavior. Adding `role="button"` provides no keyboard focus and no Enter/Space activation; the developer must implement tabindex and key handling. Think of ARIA as a promise: declaring a role obligates you to make the element behave like that role. Badly used ARIA is worse than none — 'No ARIA is better than bad ARIA.'

역할·속성·상태

Roles, Properties, and States

ARIA의 3가지 핵심 개념: ① 역할(Roles) — 요소의 용도를 정의합니다(role="button", role="dialog", role="tablist", role="alert"). ② 속성(Properties) — 비교적 고정적인 추가 정보를 제공합니다(aria-label, aria-labelledby, aria-required). ③ 상태(States) — 상호작용에 따라 변하는 현재 조건을 나타냅니다(aria-expanded, aria-checked, aria-selected, aria-disabled).

Three core ARIA concepts: ① Roles define an element's purpose (role="button", role="dialog", role="tablist", role="alert"). ② Properties provide relatively fixed additional information (aria-label, aria-labelledby, aria-required). ③ States express current conditions that change with interaction (aria-expanded, aria-checked, aria-selected, aria-disabled).

속성과 상태의 구분 요령: 상태는 사용자 상호작용으로 자주 바뀌고(아코디언 열림/닫힘), 속성은 잘 바뀌지 않습니다(필수 여부). 상태를 선언했다면 JavaScript로 실제 상태 변화에 맞춰 값을 갱신해야 합니다 — aria-expanded를 true로 박아두고 갱신하지 않는 것이 흔한 결함입니다.

Telling properties from states: states change frequently through interaction (accordion open/closed); properties rarely change (whether a field is required). If you declare a state, you must update it with JavaScript as the real state changes — hardcoding aria-expanded="true" and never updating it is a classic defect.

ARIA 사용의 다섯 규칙

The Five Rules of ARIA Use

W3C가 정리한 ARIA 사용 규칙: ① 시맨틱 HTML로 가능하면 ARIA를 쓰지 않는다(제1규칙 — `<button>` 대신 `<div role="button">` 금지). ② 꼭 필요한 경우가 아니면 기본 시맨틱을 바꾸지 않는다(예: `<h2 role="tab">` 지양, 탭 안에 h2를 넣는 방식 선호). ③ 모든 인터랙티브 ARIA 컨트롤은 키보드로 사용 가능해야 한다.

The W3C's rules of ARIA use: ① Don't use ARIA if native HTML can do it (the First Rule — `<button>` over `<div role="button">`). ② Don't change native semantics unless you truly must (avoid `<h2 role="tab">`; prefer a heading inside the tab). ③ All interactive ARIA controls must be keyboard-usable.

④ 포커스 가능한 요소에 role="presentation"이나 aria-hidden="true"를 쓰지 않는다 — 포커스는 되는데 아무것도 낭독되지 않는 "유령 요소"가 됩니다. ⑤ 모든 인터랙티브 요소에는 접근 가능한 이름(accessible name)이 있어야 한다. 이 다섯 규칙은 ARIA 결함의 대부분을 예방합니다.

④ Never put role="presentation" or aria-hidden="true" on a focusable element — you create a 'ghost': focusable but announcing nothing. ⑤ Every interactive element needs an accessible name. These five rules prevent most ARIA defects.

이름 계산과 주요 속성

Name Computation and Key Attributes

접근 가능한 이름(accessible name)은 우선순위에 따라 계산됩니다: aria-labelledby > aria-label > 네이티브 라벨(`<label>`, alt, `<caption>`) > 콘텐츠 텍스트. aria-labelledby는 다른 요소의 텍스트를 참조하고(여러 id 나열 가능), aria-label은 문자열을 직접 제공하며, aria-describedby는 이름이 아닌 보조 설명을 연결합니다.

The accessible name is computed by priority: aria-labelledby > aria-label > native labeling (`<label>`, alt, `<caption>`) > content text. aria-labelledby references other elements' text (multiple ids allowed); aria-label supplies a string directly; aria-describedby attaches supplementary description — not the name.

그 밖의 주요 속성: aria-hidden="true"(보조기술에서 서브트리 숨김 — 시각적으로는 보임), aria-required(필수 입력), aria-invalid(유효성 오류), aria-current(현재 페이지/단계 표시). aria-label은 보이는 텍스트가 없는 아이콘 버튼 등에 쓰되, 보이는 라벨이 있으면 그 라벨을 이름에 포함해야 합니다(WCAG 2.5.3 Label in Name — 음성 제어 사용자).

Other key attributes: aria-hidden="true" (hides a subtree from AT while remaining visible), aria-required, aria-invalid, and aria-current (current page/step). Use aria-label for controls with no visible text, such as icon buttons — but when a visible label exists, it must be contained in the name (WCAG 2.5.3 Label in Name, for voice control users).

Accessible name for an icon button — wrong vs. right
<!-- ❌ 이름 없는 아이콘 버튼: 스크린 리더는 "버튼"으로만 읽음 -->
<button><svg aria-hidden="true"></svg></button>

<!-- ✅ aria-label로 이름 제공 (보이는 라벨이 있으면 그 텍스트를 포함할 것) -->
<button aria-label="검색">
  <svg aria-hidden="true"></svg>
</button>
Name via aria-labelledby, supplementary hint via aria-describedby
<h2 id="ship-title">배송지 주소</h2>
<p id="ship-hint">도로명 주소를 입력하세요.</p>
<input aria-labelledby="ship-title" aria-describedby="ship-hint">

라이브 영역

Live Regions

aria-live 영역은 동적으로 변경되는 콘텐츠(알림, 오류 메시지, 로딩 상태, 검색 결과 수)를 스크린리더가 자동으로 낭독하게 합니다. aria-live="polite"는 현재 낭독이 끝난 후 알리고, aria-live="assertive"는 즉시 중단하고 알립니다. assertive는 긴급 오류에만 사용하세요.

aria-live regions make screen readers announce dynamically changing content — notifications, error messages, loading states, result counts. aria-live="polite" waits for current speech to finish; aria-live="assertive" interrupts immediately. Reserve assertive for critical errors.

관련 역할: role="status"는 polite 라이브 영역, role="alert"는 assertive 라이브 영역과 동등합니다. 실무 요령: 라이브 영역은 페이지 로드 시점부터 DOM에 존재해야 안정적으로 동작하며(내용만 갱신), 요소 자체를 동적으로 삽입하면 낭독이 누락될 수 있습니다.

Related roles: role="status" is equivalent to a polite live region and role="alert" to an assertive one. Practical tip: live regions work reliably when the container exists in the DOM from page load and only its content updates — inserting the region element itself dynamically often drops announcements.

Use polite status for updates; reserve alert for urgent errors
<!-- 폼 저장 결과 — 현재 낭독을 방해하지 않고 안내 -->
<div role="status" aria-live="polite">저장되었습니다.</div>

<!-- 긴급 오류 — assertive(role=alert)는 꼭 필요할 때만 -->
<div role="alert">세션이 만료되었습니다. 다시 로그인해주세요.</div>

Unit Quiz

7 questions · Wrong answers are saved automatically

1

WAI-ARIA 사용의 첫 번째 규칙은?

2

요소의 현재 상태(열림/닫힘, 선택됨/해제됨 등)를 나타내는 ARIA 개념은?

3

동적 알림 영역에서 '현재 읽기가 끝난 후 알린다'는 aria-live 값은?

4

'ARIA는 의미만 바꾸고 동작을 만들지 않는다'가 뜻하는 것은?

5

포커스 가능한 요소에 aria-hidden="true"를 쓰면 안 되는 이유는?

6

접근 가능한 이름(accessible name) 계산의 우선순위로 옳은 것은?

7

개발자가 커스텀 토글에 `role="switch"`와 `aria-checked`를 붙였지만 스크린 리더 사용자가 '조작이 안 된다'고 제보했습니다. 가장 가능성 높은 원인은?

Back to roadmap
Sign in to take study notes.

Comments

Loading comments...

Please sign in to write a comment.