WAI-ARIA란 무엇인가요?

이 글에서 다루는 내용
WAI-ARIA의 역할·상태·속성을 폼, 모달, 아코디언, 탭 예제로 살펴봅니다. HTML이 제공하는 기능과 ARIA가 전달하는 의미를 구분하고, 키보드 조작과 스크린 리더 테스트에서 확인할 사항을 정리합니다.
WAI-ARIA에 대해
WAI-ARIA의 정의
WAI-ARIA(Web Accessibility Initiative - Accessible Rich Internet Applications)는 스크린 리더와 음성 명령 시스템 같은 보조 기술에 웹 콘텐츠의 의미를 전달하는 W3C 표준입니다.
HTML은 <button>, <nav>, <article> 같은 시맨틱 요소로 웹 페이지의 구조와 의미를 전달합니다. 커스텀 UI에는 역할이나 상태를 별도로 표현해야 할 때가 있습니다. 다만 펼침 UI의 <details>나 모달의 <dialog>처럼 쓸 수 있는 기본 요소가 있는지 먼저 확인합니다. <div>로 만든 버튼은 보조 기술이 버튼으로 인식하지 못하고 키보드 동작도 없습니다.
WAI-ARIA는 역할(Role), 상태(State), 속성(Property) 을 정의합니다. role="button"은 보조 기술이 일반 <div>를 버튼으로 인식하게 하고, aria-expanded="true"는 드롭다운 메뉴가 열린 상태임을 알립니다.
ARIA는 HTML이 제공하지 못하는 의미만 보완합니다. 같은 의미와 동작을 가진 HTML 요소가 있다면 그 요소를 먼저 씁니다.
웹 접근성이 중요한 이유
접근성을 고려하지 않은 사이트는 일부 사용자가 기능을 아예 이용하지 못하게 만듭니다.
시각 장애가 있는 사용자는 스크린 리더(Screen Reader) 로 웹 페이지의 콘텐츠를 듣습니다. 구조가 잘못됐거나 시맨틱 정보가 부족하면 원하는 정보를 찾기 어렵습니다.
마우스를 사용할 수 없는 사용자는 키보드만으로 인터페이스를 조작합니다. 포커스가 제대로 이동하지 않거나 클릭 가능한 요소에 키보드로 접근할 수 없다면 기능을 사용할 수 없습니다.
손목 부상으로 마우스를 쓸 수 없거나 강한 햇빛 아래에서 화면을 봐야 하는 상황처럼 일시적·환경적 제약이 있을 때도 같은 기능이 도움이 됩니다.
WAI-ARIA가 필요한 이유
HTML에는 여러 시맨틱 요소가 있지만, 기본 요소만으로 상태와 관계를 모두 표현하기 어려운 동적 UI도 있습니다.
특히 다음과 같은 경우에는 WAI-ARIA가 필요합니다.
- 커스텀 UI 컴포넌트
<button>대신<div>로 버튼을 구현하면 보조 기술이 이를 버튼으로 인식하지 못합니다.
- 동적 콘텐츠 변경
- 화면의 특정 요소가 변경되었을 때 이를 보조 기술이 인식하도록 알려주지 않으면, 사용자는 변화를 감지하지 못할 수 있습니다.
- 커스텀 위젯의 포커스 정보
- 보조 기술에 활성 항목을 전달할 때 ARIA를 쓸 수 있습니다. 실제 키보드 이동과 실행 동작은 HTML 기본 기능이나 JavaScript로 구현해야 합니다.
WAI-ARIA로 HTML 요소가 본래 제공하지 않는 정보를 명시할 수 있습니다. <div role="dialog" aria-labelledby="modal-title">는 일반 <div>에 다이얼로그 역할과 제목의 관계를 부여합니다.
다만 역할을 붙여도 키보드 동작이나 포커스 관리는 생기지 않습니다. HTML의 기본 기능을 우선하고 부족한 의미만 ARIA로 보완합니다.
WAI-ARIA의 주요 개념
WAI-ARIA는 Roles(역할), States(상태), Properties(속성) 로 요소의 기능과 현재 상태, 다른 요소와의 관계를 표현합니다.
- Roles(역할): 요소가 수행하는 기능을 정의합니다. 예를 들어,
role="button"을 사용하면<div>도 버튼으로 인식되게 할 수 있습니다. - States(상태): 요소의 현재 상태를 나타내며, 동적 UI 변화를 보조 기술이 인식할 수 있도록 합니다. 예를 들어,
aria-expanded="true"는 아코디언이 열려 있음을 의미합니다. - Properties(속성): UI 요소와 관련된 추가적인 정보를 제공합니다. 예를 들어,
aria-labelledby="header-title"은 특정 제목과 요소가 연결되어 있음을 나타냅니다.
ARIA Roles(역할)
ARIA Roles는 특정 UI 요소의 기능을 명확히 정의하는 속성입니다. HTML의 시맨틱 요소만으로 충분하지 않은 경우 role 속성을 추가하여 보조 기술이 요소의 역할을 올바르게 인식하도록 할 수 있습니다.
예를 들어, <div> 요소를 버튼처럼 동작하게 만들고 싶다면 다음과 같이 정의할 수 있습니다.
<div role="button" tabindex="0">클릭하세요</div>
여기서 role="button"은 보조 기술이 이 요소를 버튼으로 인식하게 하며, tabindex="0"을 추가하면 키보드 포커스도 가능해집니다. 다만 role은 의미만 전달할 뿐 동작을 추가하지는 않으므로, 실제 버튼처럼 동작하려면 Enter와 Space 키로 실행되는 키보드 이벤트 핸들러를 JavaScript로 직접 구현해야 합니다.
Landmark Roles(랜드마크 역할)
랜드마크 역할은 페이지의 주요 영역을 명확히 정의하여 보조 기술이 콘텐츠를 더 쉽게 탐색할 수 있도록 합니다. 아래는 시맨틱 요소를 사용할 수 없는 상황을 가정한 예시입니다.
<div role="banner">웹사이트 제목</div>
<div role="navigation">
<ul>
<li><a href="/">홈</a></li>
<li><a href="/about">소개</a></li>
</ul>
</div>
<div role="main">
<h1>메인 콘텐츠</h1>
</div>
위 코드에서 role="banner", role="navigation", role="main"은 각각 사이트 공통 머리말, 내비게이션, 주요 콘텐츠 영역을 나타냅니다. 단, 페이지 수준의 <header>, <nav>, <main>은 해당 역할을 암시적으로 가집니다. <article>이나 <section> 내부의 <header>는 banner가 아닙니다. 따라서 시맨틱 요소를 쓸 수 있다면 동일한 role을 중복으로 지정하지 않는 것이 좋습니다.
Widget Roles(위젯 역할)
위젯 역할은 버튼, 다이얼로그, 탭과 같은 UI 요소의 의미를 보조 기술에 전달합니다. 역할을 지정하는 것만으로 접근성이 보장되지는 않습니다.
<div role="dialog" aria-labelledby="modal-title">
<h2 id="modal-title">로그인</h2>
<button aria-label="닫기">X</button>
</div>
role="dialog"는 이 영역이 다이얼로그임을, aria-labelledby는 어느 제목을 읽어야 하는지를 전달합니다.
ARIA States(상태)
ARIA 상태 속성은 UI 요소의 현재 상태를 나타내며, 사용자의 상호작용에 따라 변하는 동적 정보를 제공합니다.
aria-checked: 체크박스나 라디오 버튼이 선택되었는지를 나타냅니다.aria-disabled: 요소가 비활성화된 상태인지 여부를 지정합니다.aria-expanded: 아코디언이나 드롭다운이 열려 있는지를 나타냅니다.aria-hidden: 특정 요소를 보조 기술이 무시하도록 설정합니다.
<button aria-expanded="true" aria-controls="content">더보기</button>
<div id="content">추가 정보</div>
여기서 aria-expanded="true"는 해당 버튼이 제어하는 영역이 현재 펼쳐져 있음을 의미합니다.
ARIA Properties(속성)
ARIA 속성은 특정 UI 요소의 설명이나 관계를 명확하게 정의하는 데 사용됩니다.
aria-labelledby: 요소가 어떤 제목과 연결되어 있는지를 지정합니다.aria-describedby: 요소에 대한 추가 설명을 제공합니다.
<h2 id="header-title">제품 목록</h2>
<ul aria-labelledby="header-title">
<li>제품 A</li>
<li>제품 B</li>
</ul>
위 코드에서 aria-labelledby="header-title" 속성을 사용하면 보조 기술이 목록과 제목을 함께 읽어줄 수 있습니다.
WAI-ARIA와 HTML5의 역할 분담
<button>, <input>, <nav>, <header> 같은 시맨틱 요소에는 역할과 기본 동작이 이미 들어 있습니다. 같은 기능의 HTML 요소가 있다면 ARIA로 다시 만들지 않습니다.
✅ 올바른 예시 (HTML 기본 요소 사용)
<button>클릭하세요</button>
🚫 잘못된 예시 (ARIA를 불필요하게 사용)
<div role="button" tabindex="0">클릭하세요</div>
role="button"은 의미만 바꿉니다. <button>이 기본으로 제공하는 키보드 실행과 폼 동작까지 더해 주지는 않습니다.
정리
role, state, property는 HTML만으로 표현하기 어려운 의미를 전달합니다. 기본 요소가 이미 제공하는 정보는 중복하지 않습니다.
WAI-ARIA 적용 사례
폼, 모달 다이얼로그, 아코디언과 탭을 예로 ARIA가 보완하는 정보를 확인합니다.
Form 요소에 WAI-ARIA 적용하기
폼의 레이블 연결은 HTML의 <label>만으로 충분합니다. WAI-ARIA는 <label>이 담지 못하는 부가 설명이나 검증 상태를 전달할 때 씁니다.
aria-describedby를 활용한 폼 입력
<label for="email">이메일</label>
<input type="email" id="email" aria-describedby="email-hint" />
<p id="email-hint">이메일 주소를 입력하세요.</p>
for="email": 네이티브<label>연결만으로 입력 필드의 접근 가능한 이름이 부여되므로,aria-labelledby를 중복으로 지정할 필요가 없습니다.aria-labelledby는 네이티브 레이블보다 우선 적용되기 때문에, 여러 요소의 텍스트를 조합해 이름을 붙이는 등 네이티브 레이블만으로 표현하기 어려울 때 사용할 수 있습니다.aria-describedby="email-hint": 입력 필드에 대한 추가 설명을 제공합니다.
aria-invalid와 aria-required를 활용한 유효성 검사
<input type="text" aria-required="true" aria-invalid="true" />
aria-required="true": 해당 필드가 필수 입력 항목임을 의미합니다.aria-invalid="true": 잘못된 입력이 감지되었음을 나타냅니다.
이 속성들은 상태를 전달하지만 입력을 검증하거나 제출을 막지는 않습니다. 네이티브 입력에는 required를 우선 검토하고, aria-invalid는 실제 검증 결과에 맞춰 갱신합니다.
Modal Dialog에서 WAI-ARIA 활용하기
모달 다이얼로그는 웹에서 자주 사용되지만, 접근성을 고려하지 않으면 키보드 사용자나 스크린 리더 사용자가 모달을 인식하지 못할 수 있습니다.
role="dialog"와 aria-labelledby를 활용한 모달
<div
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
aria-describedby="modal-description"
>
<h2 id="modal-title">로그인</h2>
<p id="modal-description">이메일과 비밀번호를 입력하세요.</p>
<button aria-label="닫기">X</button>
</div>
role="dialog": 보조 기술이 해당 요소를 대화 상자로 인식하도록 합니다.aria-modal="true": 대화 상자가 모달임을 나타내며, 열려 있는 동안 배경 콘텐츠가 비활성 상태임을 보조 기술에 전달합니다.aria-labelledby="modal-title": 다이얼로그의 제목을 명확하게 지정합니다.aria-describedby="modal-description": 다이얼로그의 내용을 설명합니다.
aria-modal="true"는 의미만 전달할 뿐 배경을 실제로 비활성화하지 않습니다. 모달 밖 콘텐츠에는 inert 또는 이에 준하는 처리를 적용해 포커스와 포인터 접근을 막아야 합니다. 다이얼로그를 포함한 상위 요소에 aria-hidden="true"를 설정하면 다이얼로그까지 접근성 트리에서 사라질 수 있으므로 주의합니다.
키보드 포커스 유지
모달이 열릴 때, 사용자의 키보드 포커스를 모달 내부에 유지하고 닫힐 때는 원래 위치로 돌아가도록 처리해야 합니다. 이를 위해 JavaScript로 focus()를 적절히 제어해야 합니다.
<button id="open-modal">모달 열기</button>
<div id="modal" role="dialog" aria-modal="true" aria-labelledby="modal-title" hidden>
<h2 id="modal-title">로그인</h2>
<button id="close-modal">닫기</button>
</div>
<script>
const openModal = document.getElementById("open-modal");
const closeModal = document.getElementById("close-modal");
const modal = document.getElementById("modal");
openModal.addEventListener("click", () => {
modal.hidden = false;
closeModal.focus(); // 모달이 열릴 때 닫기 버튼에 포커스
});
closeModal.addEventListener("click", () => {
modal.hidden = true;
openModal.focus(); // 모달이 닫힐 때 원래 위치로 포커스 복귀
});
</script>
이렇게 하면 모달이 열릴 때 초기 포커스가 모달 내부로 이동하고, 닫히면 원래 위치로 돌아가게 됩니다. 다만 위 코드는 초기 포커스만 이동시킬 뿐 Tab 키 이동을 모달 안에 가두지는 못합니다. Tab 순환이 모달 내부에서만 이루어지도록 하는 포커스 트랩과 Escape 키로 닫는 동작도 추가로 구현해야 합니다.
Custom UI 컴포넌트에서 WAI-ARIA 적용
기본 HTML 요소로 제공되지 않는 아코디언(Accordion), 탭(Tab)과 같은 UI 컴포넌트는 WAI-ARIA를 활용하여 접근성을 높일 수 있습니다.
아코디언(Accordion)에 WAI-ARIA 적용
아코디언은 펼치거나 닫을 수 있는 UI 컴포넌트로, aria-expanded 속성을 활용하여 현재 상태를 나타낼 수 있습니다.
<button aria-expanded="false" aria-controls="content">더보기</button>
<div id="content" hidden>추가 정보</div>
<script>
const button = document.querySelector("button");
const content = document.getElementById("content");
button.addEventListener("click", () => {
const isExpanded = button.getAttribute("aria-expanded") === "true";
button.setAttribute("aria-expanded", !isExpanded);
content.hidden = isExpanded;
});
</script>
aria-expanded="false": 아코디언이 닫힌 상태임을 나타냅니다.aria-controls="content": 버튼이 제어하는 콘텐츠를 명시합니다.- JavaScript를 활용하여 상태 변경 시
aria-expanded값을 업데이트합니다.
탭(Tab) 컴포넌트에서 WAI-ARIA 적용
탭(Tab) UI를 구현할 때, role="tablist", role="tab", role="tabpanel"을 사용하여 보조 기술이 탭의 구조를 인식할 수 있도록 할 수 있습니다.
<div role="tablist">
<button role="tab" aria-selected="true" aria-controls="panel1" id="tab1">
탭 1
</button>
<button role="tab" aria-selected="false" aria-controls="panel2" id="tab2">
탭 2
</button>
</div>
<div id="panel1" role="tabpanel" aria-labelledby="tab1">탭 1 내용</div>
<div id="panel2" role="tabpanel" aria-labelledby="tab2" hidden>탭 2 내용</div>
<script>
const tabs = document.querySelectorAll('[role="tab"]');
const panels = document.querySelectorAll('[role="tabpanel"]');
tabs.forEach((tab) => {
tab.addEventListener("click", () => {
tabs.forEach((t) => t.setAttribute("aria-selected", "false"));
panels.forEach((p) => (p.hidden = true));
tab.setAttribute("aria-selected", "true");
document.getElementById(tab.getAttribute("aria-controls")).hidden = false;
});
});
</script>
role="tablist": 탭 요소들을 그룹화합니다.role="tab": 개별 탭을 정의합니다.aria-selected="true": 현재 활성화된 탭을 나타냅니다.role="tabpanel": 탭의 내용을 감싸는 요소를 정의합니다.aria-labelledby="tab1": 해당 탭과 연결된 콘텐츠를 명시합니다.
이렇게 구현하면 보조 기술이 탭 구조를 올바르게 인식할 수 있습니다. 다만 APG 탭 패턴을 완전히 준수하려면 화살표 키로 탭 사이를 이동하는 키보드 인터랙션(roving tabindex)을 추가로 구현해야 합니다.
정리
ARIA 속성은 폼의 설명과 검증 상태, 모달의 이름과 상태, 커스텀 위젯의 관계를 전달합니다. 포커스 이동과 키보드 조작은 별도로 구현하고 함께 시험해야 합니다.
WAI-ARIA 사용 시 주의할 점
ARIA가 실제 동작과 어긋나면 보조 기술에 잘못된 정보를 전달합니다. 다음 항목을 적용 전에 확인합니다.
HTML5 기본 요소와 중복 사용 주의
HTML5는 이미 접근성을 고려한 시맨틱 요소(<button>, <nav>, <input> 등)를 제공합니다. 따라서, WAI-ARIA는 HTML의 기본 기능이 부족한 경우에만 보완적으로 사용해야 합니다.
예를 들어, <button> 요소는 본래 클릭 가능한 버튼 역할을 하므로, 추가적인 role="button" 속성은 불필요합니다.
✅ 올바른 예시 (HTML 기본 요소 사용)
<button>클릭하세요</button>
🚫 잘못된 예시 (불필요한 ARIA 사용)
<div role="button" tabindex="0">클릭하세요</div>
<div>에 role="button"을 붙이는 방식은 <button>을 사용할 수 없을 때만 검토합니다.
과도한 ARIA 사용의 문제점
WAI-ARIA는 웹 접근성을 향상시키기 위해 존재하지만, 과도하게 사용하면 오히려 혼란을 초래할 수 있습니다.
- 잘못된
role은 요소의 본래 의미를 다른 역할로 덮어쓸 수 있습니다. - ARIA로 역할을 바꿔도 브라우저 기본 동작은 바뀌지 않습니다. 전달한 역할과 실제 조작 방식이 어긋날 수 있습니다.
aria-hidden="true"를 남용하면 콘텐츠가 보이지 않는 사용자에게 완전히 무시될 수 있습니다.
🚫 잘못된 예시 (과도한 ARIA 사용)
<a href="/" role="button">홈으로 이동</a>
이동을 위한 <a href>에는 링크 역할을 유지합니다. 화면 안의 동작을 실행한다면 <button>이 적합합니다. 둘 다 클릭할 수 있어도 역할과 키보드 조작 방식이 다릅니다.
✅ 올바른 예시
<a href="/">홈으로 이동</a>
이동에는 링크를, 화면 안의 동작에는 버튼을 사용하면 역할과 기본 조작이 일치합니다.
스크린 리더와 브라우저 조합 확인하기
WAI-ARIA 속성은 스크린 리더와 브라우저의 조합에 따라 다르게 읽힐 수 있습니다. 지원 대상 조합에서 직접 테스트해야 합니다.
WAI-ARIA 테스트 도구
- axe DevTools: 브라우저 확장 프로그램을 통해 WAI-ARIA 문제를 자동 감지할 수 있습니다.
- NVDA (Windows) / VoiceOver (macOS): 실제 스크린 리더를 사용하여 WAI-ARIA 적용 결과를 확인할 수 있습니다.
- Lighthouse (Chrome DevTools): 웹 접근성 검사를 수행하고 문제를 보고해 줍니다.
자동 검사가 통과해도 브라우저와 스크린 리더 조합에 따라 읽는 방식이 다를 수 있습니다. 지원할 조합에서 직접 확인합니다.
정리
HTML 기본 요소를 먼저 쓰고 ARIA는 부족한 의미에만 추가합니다.
- 불필요한
role속성 추가를 피합니다. - 기본 HTML 요소가 제공하는 기능을 대체하지 않습니다.
- 스크린 리더와 브라우저 지원 여부를 항상 확인합니다.
역할과 실제 동작이 일치하는지도 키보드와 보조 기술로 확인합니다.
WAI-ARIA 모범 사례
ARIA 속성만으로 키보드 조작이나 동적 콘텐츠 알림이 완성되지는 않습니다. 속성과 실제 동작을 함께 구현한 뒤 자동 검사와 보조 기술로 검증합니다.
aria-live를 활용한 동적 콘텐츠 업데이트
화면의 상태 메시지가 바뀌어도 포커스가 그 영역으로 이동하지 않으면 스크린 리더는 변화를 알리지 않을 수 있습니다. aria-live는 영역의 변경 내용을 읽어야 한다는 정보를 보조 기술에 전달합니다.
aria-live의 동작 방식
aria-live="polite": 현재 읽기를 방해하지 않는 시점에 변경 내용을 알리도록 요청aria-live="assertive": 현재 읽기를 중단하고 우선 알리도록 요청(긴급한 알림에 사용)
aria-live 적용 예시
<p id="status" aria-live="polite">결과가 여기에 표시됩니다.</p>
<button onclick="updateStatus()">결과 보기</button>
<script>
function updateStatus() {
document.getElementById("status").textContent = "검색이 완료되었습니다.";
}
</script>
위 코드에서 버튼 클릭 시 aria-live="polite"가 설정된 <p> 태그가 변경되며, 보조 기술은 이 내용을 사용자에게 전달합니다.
aria-live 영역을 너무 많이 만들면 알림이 겹쳐 사용자를 혼란스럽게 할 수 있습니다. 값이 자주 바뀌는 영역은 모든 변화를 읽게 하기보다, 사용자에게 필요한 상태만 모아 적절한 간격으로 알립니다.
키보드 네비게이션과 ARIA의 관계
웹 접근성의 핵심 요소 중 하나는 모든 인터랙티브 UI 요소를 키보드만으로 조작할 수 있도록 하는 것입니다. HTML의 tabindex로 포커스를 관리하고, ARIA 속성으로 보조 기술에 활성 항목을 전달할 수 있습니다. tabindex는 ARIA 속성이 아닙니다.
tabindex와 aria-activedescendant를 활용한 키보드 포커스 제어
tabindex="0": 요소를 키보드 탐색 가능하도록 설정tabindex="-1": 요소가 포커스를 받을 수 있지만,Tab키로는 이동할 수 없음aria-activedescendant: 현재 활성화된 요소를 명시적으로 지정하여, 스크린 리더가 올바른 항목을 읽도록 함
키보드 네비게이션 예시 (커스텀 드롭다운)
<div role="listbox" tabindex="0" aria-activedescendant="item1">
<div id="item1" role="option" tabindex="-1">옵션 1</div>
<div id="item2" role="option" tabindex="-1">옵션 2</div>
</div>
함께 구현할 사항:
role="listbox"와role="option"으로 드롭다운의 구조를 전달합니다.aria-activedescendant는 현재 활성 항목을,aria-selected는 선택 상태를 나타내므로 각각 갱신합니다.keydown이벤트로 화살표 키 이동을 구현합니다.
접근성 테스트 도구(axe, Lighthouse, NVDA) 활용법
자동 검사와 실제 키보드·스크린 리더 테스트를 함께 진행합니다.
axe DevTools (자동 접근성 검사)
- 브라우저 확장 프로그램으로 접근성 문제를 자동 감지합니다.
- ARIA 속성의 잘못된 사용을 확인합니다.
- 사용 방법: Chrome DevTools → axe 탭에서 실행
Lighthouse (Chrome DevTools 내장 접근성 테스트)
- 웹사이트의 접근성 검사 결과와 개선 항목을 확인합니다.
- 사용 방법: Chrome DevTools → Lighthouse → Accessibility 선택 후 실행
NVDA (Windows) / VoiceOver (macOS)
- 실제 스크린 리더가 이름·역할·상태를 어떻게 읽는지 확인합니다.
- 사용 방법: NVDA(무료) 다운로드 후 활성화 → 웹페이지 탐색
테스트 시 고려할 점:
- ARIA 속성이 화면 상태와 맞는지 확인합니다.
- 키보드만으로 모든 기능을 수행할 수 있는지 점검합니다.
- 보조 기술에서 읽는 순서와 안내 문구를 확인합니다.
정리
구현을 마치면 다음을 함께 확인합니다.
- 동적 콘텐츠의 변경 사항이 필요한 시점에 전달되는가?
tabindex와aria-activedescendant가 실제 키보드 이동과 일치하는가?- 자동 검사와 실제 스크린 리더 테스트를 모두 통과하는가?
결론
WAI-ARIA는 HTML만으로 표현하기 어려운 역할·상태·관계를 보조 기술에 전달합니다. 기본 HTML 요소를 먼저 사용하고, 부족한 의미만 ARIA로 보완합니다. 속성값은 화면 상태와 함께 갱신하며 키보드 동작과 포커스 관리는 별도로 구현합니다.
설계와 구현, 테스트에서는 다음 항목을 확인합니다.
시맨틱 마크업을 먼저 사용하기
HTML이 기본으로 제공하는 의미와 동작을 먼저 사용합니다.
role="button"대신<button>사용role="navigation"대신<nav>사용
키보드 조작 확인하기
- 키보드 사용자가 모든 인터랙티브 요소에 접근할 수 있어야 합니다.
- 모달이나 드롭다운이 열리고 닫힐 때 포커스의 이동과 복귀를 확인합니다.
필요한 ARIA만 추가하기
- 상태 메시지는 필요에 따라
aria-live로 알립니다. - 커스텀 UI에는 실제 역할과 상태에 맞는
role,aria-expanded,aria-labelledby등을 적용합니다.
자동 검사와 보조 기술로 검증하기
- Lighthouse와 axe DevTools로 자동 검사합니다.
- 지원 대상 브라우저에서 NVDA나 VoiceOver로 읽기 결과를 확인합니다.
실제 화면에서는 기본 HTML 요소를 먼저 선택하고, 부족한 의미만 ARIA로 보완합니다. 이후 키보드만으로 조작해 보고 스크린 리더가 읽는 이름·역할·상태가 화면과 일치하는지 확인합니다.
