쇼핑몰에서 “장바구니에 담기"를 누르면 화면 오른쪽 위 배지의 숫자가 3에서 4로 바뀝니다. 눈으로 보는 사람에게는 그걸로 충분한 피드백이죠. 그런데 화면을 읽어주는 소프트웨어인 스크린 리더로 웹을 쓰는 사람에게는요? 페이지 어딘가의 숫자가 조용히 바뀐 것만으로는 아무것도 전달되지 않습니다. 담겼는지, 몇 개인지, 실패했는지 알 길이 없어요.
이 문제를 다루는 것이 WCAG의 성공 기준 4.1.3 상태 메시지(Status Messages)입니다. 그리고 이걸 구현하는 도구가 aria-live고요. 그런데 붙이는 것까지는 쉬운데, 진짜 고민은 그다음에 시작됩니다. 개수가 연달아 바뀌면 스크린 리더는 그걸 다 읽을까? polite와 assertive는 실제로 뭐가 다를까? 아이콘이나 소리로만 표시되는 상태는요? 이 글에서 하나씩 실험하며 확인해봅니다.
모든 예제는 직접 만져볼 수 있는 aria-live 상태 메시지 데모 페이지에 올려뒀습니다. 글을 읽으며 같이 눌러보시면 좋아요.
이 글은 화요일 저녁에 시작됐습니다 — a11ykr 번역·문서화 모임#
시작하기 전에, 이 글이 나온 곳을 소개하고 싶어요. 본론이 급하시면 상태 메시지 정의로 바로 내려가셔도 됩니다.
a11ykr는 한국의 접근성 실무자들이 모여 W3C 접근성 문서를 한국어로 번역하고 문서화하는 커뮤니티입니다. 매주 화요일 저녁의 정기 모임에서는 지금 WCAG 2.2 Understanding 문서를 함께 번역하며 스터디하고 있어요. 성공 기준 하나를 맡은 사람이 발표하면, 다 같이 원문을 뜯어보며 “이 문장이 실무에서 무슨 뜻이지?“를 토론하는 방식입니다. 저도 여기에 참여하고 있고, 평소에도 접근성 관련 논의가 생기면 디스코드에서 대화가 이어집니다.
- a11ykr 그룹 공식 소개 — 그룹과 활동, 접근성 자료가 모이는 곳
- a11ykr 디스코드 — 같이 접근성 이야기하는 채널
- GitHub 저장소 — 번역 참여와 수정 제안은 여기로
WCAG 2.2가 어떤 표준이고 무엇이 새로 들어왔는지는 WCAG 2.2 신규 성공기준 6개에서 정리한 적이 있어요. 이번 주 모임에서 다룬 성공 기준이 바로 4.1.3 상태 메시지였습니다. 발표를 들으며 “장바구니 개수가 계속 늘어나면 스크린 리더가 그걸 다 읽어주나?” 같은 질문이 꼬리를 물었고, 문서만 읽어서는 답이 안 나오니 직접 만들어 확인해보기로 했어요. 그 결과물이 이 글입니다. 표준 문서를 혼자 읽으면 졸리지만 여럿이 뜯어보면 글감이 나옵니다. 관심 있으신 분은 GitHub 저장소에 편하게 들러보세요.
상태 메시지란 무엇인가 — WCAG 4.1.3이 요구하는 것#
WCAG(웹 콘텐츠 접근성 지침)는 상태 메시지를 이렇게 정의합니다.
맥락 변화(change of context)가 아니면서, 행동의 성공이나 결과, 애플리케이션의 대기 상태, 프로세스의 진행 상황, 또는 오류의 존재에 관한 정보를 사용자에게 제공하는 콘텐츠 변화
“검색 결과 5건”, “장바구니 5개”, “잘못된 입력입니다”, “저장 중…”. 전부 여기에 해당합니다. 그리고 4.1.3은 이런 메시지에 대해 딱 한 가지를 요구합니다.
마크업 언어로 구현된 콘텐츠에서, 상태 메시지는 역할(role)이나 속성을 통해 프로그램적으로 판별될 수 있어서, 초점을 받지 않고도 보조기술이 사용자에게 제시할 수 있어야 한다. (레벨 AA)
여기서 보조기술은 스크린 리더처럼 사용자를 대신해 콘텐츠를 읽거나 조작해주는 소프트웨어·하드웨어를 말합니다. 그리고 핵심은 “초점을 받지 않고도"입니다. 초점(focus)은 키보드 입력이 향하는 현재 위치를 말하고요. 대화상자(dialog)처럼 초점을 가져가는 UI는 애초에 이 기준의 대상이 아니에요. 초점이 이동하면 그건 맥락 변화라서, 스크린 리더가 어차피 읽게 되거든요. 4.1.3이 겨냥하는 건 화면 한구석에서 조용히 바뀌는 콘텐츠입니다. 사용자의 작업을 끊지 않으면서도, 그 변화를 들을 수 있게 하라는 거죠.
정의를 뒤집으면 중요한 결론이 하나 나옵니다. 성공·대기·진행·오류 중 어디에도 해당하지 않는 변화는 상태 메시지가 아니고, 4.1.3의 요구 대상도 아니라는 것입니다.
aria-live polite vs assertive — 줄을 서느냐, 끼어드느냐#
상태 메시지를 스크린 리더에 전달하는 표준 도구가 라이브 영역(live region)입니다. aria-live 속성이 붙은 요소는 “이 안의 콘텐츠가 바뀌면 사용자에게 알려달라"고 보조기술에 선언하는 영역이 돼요. 값은 두 가지가 실질적으로 쓰입니다.
ARIA 명세의 정의를 그대로 옮기면 이렇습니다.
| 값 | 명세의 정의 | 한 줄 요약 |
|---|---|---|
polite | 다음의 자연스러운 기회에(now speaking 중인 문장이 끝났을 때, 사용자가 타이핑을 멈췄을 때 등) 제시되어야 한다 | 줄을 선다 |
assertive | 최우선 순위를 가지며 즉시 제시되어야 한다 | 끼어든다 |
카페 계산대에 비유하면 polite는 줄 맨 뒤에 서는 손님이고, assertive는 “죄송한데 저 이것만요” 하며 맨 앞으로 들어오는 손님입니다. 명세는 여기에 경고를 하나 붙여둡니다. 끼어들기는 사용자를 혼란스럽게 하거나 하던 작업을 못 마치게 할 수 있으니, 중단이 불가피한 경우가 아니라면 assertive를 쓰지 말라(SHOULD NOT)고요. 실제로 WCAG Understanding 문서의 실패 사례 목록에도 “중요하면서 시급한 콘텐츠가 아닌데도 role="alert"나 aria-live="assertive"를 쓰는 것"이 올라 있습니다.
매번 aria-live를 손으로 붙일 필요는 없습니다. 역할(role)에 기본값이 내장된 게 있거든요.
<!-- role="status": aria-live="polite" + aria-atomic="true"가 암묵 적용 -->
<div role="status">장바구니 5개</div>
<!-- role="alert": aria-live="assertive" + aria-atomic="true"가 암묵 적용 -->
<div role="alert">세션이 만료되었습니다</div>aria-atomic="true"는 “바뀐 글자만 말고 영역 전체를 다시 읽어라“라는 뜻입니다. 개수만 4→5로 바뀌어도 “장바구니 5개"라고 온전한 문장으로 읽히는 이유죠. 일반적인 상태 메시지에는 role="status", 지금 당장 알아야 하는 오류에는 role="alert" — 이 두 가지만 기억해도 대부분의 상황이 커버됩니다. 채팅 로그처럼 쌓이는 이력 자체가 정보일 때는 role="log"라는 제3의 선택지도 있는데, 지금처럼 최신 값 하나만 의미가 있다면 role="status"가 맞습니다. 폼 오류 알림에서 role="alert"를 실전으로 쓰는 법은 폼 접근성 마스터하기에서, ARIA 속성 전반의 기초는 ARIA 실전 가이드에서 다뤘습니다.
하나 더, 실무에서 가장 많이 밟는 지뢰가 있습니다. 라이브 영역은 내용이 바뀌기 전에 DOM에 미리 존재해야 합니다. 메시지가 생길 때 role="status" 요소째로 새로 삽입하면 스크린 리더가 놓치는 경우가 많아요. 빈 영역을 페이지 로드 때부터 두고, 알릴 일이 생기면 그 안의 텍스트만 바꾸는 게 정석입니다. 실패 유형 F103도 “동적 콘텐츠가 추가되기 전에 역할이나 속성이 설정되어 있지 않으면 실패를 예고한다"고 못 박아둔 지점이에요. 같은 텍스트를 다시 넣으면 발화가 생략될 수 있다는 함정까지 포함해, 라이브 영역이 침묵하는 원인들은 알림이 안 읽히는 이유 — ARIA 라이브 리전 제대로 쓰기에서 따로 정리했습니다.
장바구니에 10개를 연달아 담으면 어떻게 읽힐까#
이제 스터디에서 나온 질문으로 들어갑니다. 사용자가 담기 버튼을 연타해서 장바구니가 1개, 2개, 3개… 10개까지 늘어난다면, 스크린 리더는 이걸 어떻게 처리할까요? 짧은 답은 이렇습니다. polite는 밀리고, assertive는 끊깁니다.
버튼을 누르는 동안 스크린 리더는 이미 말을 하고 있습니다(버튼 이름을 읽거나, 앞선 알림을 읽는 중이거나). 그 위로 라이브 영역 업데이트가 쏟아지는 상황이에요. 스펙대로라면 이렇게 갈라집니다.

polite라면 밀린 알림이 큐에 쌓입니다. 지금 읽는 말이 끝날 때까지 기다렸다가 다음 알림을 읽으니, 클릭이 발화보다 빠르면 “장바구니 1개… 2개… 3개…“가 차곡차곡 밀립니다. 클릭은 3초 만에 끝났는데 낭독은 그 뒤로도 한참 이어질 수 있어요. 스펙 모형대로라면 스크린 리더는 밀린 발화를 끝까지 성실하게 읽게 됩니다. 문제는 바로 그 성실함이죠.
assertive라면 앞의 말이 계속 끊깁니다. 새 알림이 이전 발화를 자르고 들어오니, “장바구… 장바구… 장바구니 10개"처럼 중간이 전부 잘리고 마지막 것만 온전히 들립니다. 결과만 들리니 오히려 낫지 않냐고 생각할 수 있는데, 명세는 끼어들기 자체가 사용자를 혼란에 빠뜨린다고 경고하고, ARIA 명세에는 “assertive 변화가 발생하면 사용자 에이전트나 보조기술이 큐에 쌓인 변화를 지워버릴 수도 있다(MAY)“는 문장까지 있습니다. 다른 알림까지 날아갈 수 있다는 뜻이에요.
데모 1번에 두 방식의 장바구니를 나란히 두고, 발화 큐를 눈으로 볼 수 있는 가상 스크린 리더 창을 붙여뒀습니다. “10개 연속 담기"를 누르면 polite 쪽은 대기 항목이 쌓이고 assertive 쪽은 취소선이 죽죽 그어지는 걸 볼 수 있어요.
주의할 점: 데모의 가상 스크린 리더는 어디까지나 명세가 말하는 우선순위의 모형입니다. 실제 제품은 저마다 다르게 동작해요. 밀린 항목을 건너뛰기도 하고, 같은 영역의 연속 변화를 합쳐 마지막 값만 읽기도 합니다. 제 맥 VoiceOver로 이 데모를 실측해보니 polite는 10개를 정말 끝까지 다 읽었고, assertive는 마지막 것만 온전히 들렸고, 뒤에 나올 디바운스는 한 번만 읽었습니다. 스펙 모형 그대로였지만, 제품과 버전에 따라 얼마든지 다를 수 있어요. 그래서 데모 페이지의 알림 영역은 전부 진짜로 만들어뒀습니다. NVDA(윈도우용 무료 스크린 리더)나 VoiceOver(맥 내장, Cmd+F5)를 켜고 같은 버튼을 누르면, 여러분 환경의 실제 동작을 그대로 들을 수 있습니다. 이 확인 과정을 대신해줄 수 있는 자동화 도구는 없어요.
어느 쪽이든 연타 상황에서는 결과가 시끄럽거나 어수선합니다. 장바구니 개수는 분명 상태 메시지가 맞고 알려야 하는 정보인데, 매 변화를 실시간으로 중계하는 건 답이 아니라는 거죠. 그럼 어떻게 해야 할까요?
디바운스 타이머로 행동이 끝난 뒤 한 번만 말하기#
Understanding 문서는 이 지점을 정확히 짚고 있습니다.
애플리케이션이 스크린 리더 사용자에게 너무 “수다스러워질(chatty)” 위험이 있다. 적절한 피드백 수준을 찾기 위해 사용자 테스트를 수행해야 한다.
스터디에서 “조언 기법(Advisory Techniques)에서 이 문제를 다룬다"는 얘기가 나와서 확인해봤는데, 절반만 맞았습니다. 조언 기법 목록에 있는 건 role="timer" 사용, aria-alertdialog로 오류 식별(ARIA18), 불필요한 알림을 사용자가 끌 수 있게 만들기(SCR14) 같은 항목들이에요. “타이머로 모아서 알리기"라는 기법이 그 이름으로 등재돼 있지는 않습니다.
다만 위 인용처럼 문서가 수다스러움을 명시적으로 경고하고 있으니, 이를 실무 패턴으로 구현한 것이 지금부터 볼 디바운스(debounce)입니다. 연속된 이벤트가 잠잠해질 때까지 기다렸다가 한 번만 실행하는 기법이죠.
아이디어는 화면과 발화를 분리하는 겁니다. 눈에 보이는 숫자는 즉시 바뀌어야 하지만, 귀로 듣는 알림은 행동이 끝난 뒤 최종 결과 한 번이면 충분하거든요.
<button type="button" id="add-btn">장바구니에 담기</button>
<!-- 화면 표시용 — 라이브 영역이 아니므로 바뀌어도 발화되지 않는다 -->
<span id="cart-count">장바구니 비어 있음</span>
<!-- 발화 전용 — 화면 밖에 숨겨두고, 페이지 로드 때부터 존재해야 한다 -->
<div role="status" class="sr-only" id="cart-live"></div>/* 화면에서는 숨기고 스크린 리더에는 남기는 표준 유틸리티 */
.sr-only {
position: absolute;
width: 1px; height: 1px;
margin: -1px; padding: 0;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
border: 0;
}const addBtn = document.getElementById('add-btn');
const cartCount = document.getElementById('cart-count');
const cartLive = document.getElementById('cart-live');
let count = 0;
let pending = null;
addBtn.addEventListener('click', () => {
count++;
cartCount.textContent = `장바구니 ${count}개`; // 화면은 즉시
// 클릭이 이어지는 동안에는 발화를 미룬다
clearTimeout(pending);
pending = setTimeout(() => {
cartLive.textContent = `장바구니 ${count}개`; // 발화는 마지막 클릭 0.6초 뒤 한 번
}, 600);
});10번을 연타해도 스크린 리더가 듣는 건 “장바구니 10개” 한 번입니다. 데모 2번에서 1번과 같은 조작을 해보면 가상 스크린 리더 창의 차이가 한눈에 보여요.
대기 시간은 정답이 없지만 500~1000ms 사이에서 시작해보는 걸 권합니다. 너무 짧으면 연타 중에 발화가 새어 나오고, 너무 길면 “눌렀는데 반응이 없네?” 하는 침묵이 생기거든요. Understanding 문서가 사용자 테스트를 권고하는 이유가 이겁니다.
두 가지는 선을 그어둘게요. 디바운스로 모을 대상은 개수처럼 반복되는 상태뿐입니다. 담기 실패 같은 오류는 별도의 role="alert" 경로로 즉시 내보내야 하고, 성공 카운트와 한 영역에 섞으면 마지막 발화가 실패를 덮어버립니다. 그리고 polite 알림은 사용자가 그 사이 다른 곳으로 이동하면 유실될 수 있는 일회성 신호예요. 언제든 다시 읽을 수 있는 본체는 화면의 개수 텍스트고, 알림은 그 위의 보조 채널이라고 생각하는 게 안전합니다.
앞으로의 이야기: 이 발화 큐 관리의 고통을 표준 차원에서 풀려는 ariaNotify API 논의도 진행 중입니다. Understanding 문서의 기법 목록에 ARIA27(ariaNotify로 진행률 전달)이 이미 올라와 있어요. 다만 브라우저 지원이 아직 일러서, 당분간의 정답은 여전히 라이브 영역입니다.
반대로 라이브 영역 자체를 빼먹으면 어떻게 될까요? 텍스트는 눈에 보이게 바뀌지만 role도 aria-live도 없는 경우, 스크린 리더는 아무 말도 하지 않습니다. WCAG는 이걸 실패 유형 F103으로 문서화해뒀고, 데모 3번에서 이 “조용한 실패"를 직접 확인할 수 있습니다.
아이콘·소리 상태도 상태 메시지다 — 비텍스트 상태 콘텐츠#
상태가 늘 텍스트로 표시되는 건 아니죠. 저장 버튼 옆에 도는 스피너, 완료를 뜻하는 체크 아이콘, “딩동” 하는 알림음. 이런 것도 4.1.3의 대상일까요?
Understanding 문서에 이 경우를 다루는 절이 따로 있습니다(Non-textual status content). 요지는 이렇습니다.
콘텐츠 변화는 텍스트 변화에 국한되지 않는다. 아이콘이나 소리가 상태 메시지를 나타내는 경우, 이 정보는 두 가지의 조합으로 스크린 리더에 전달된다. 1) 대체 텍스트에 관한 기존 WCAG 요구사항(성공 기준 1.1.1 비텍스트 콘텐츠), 그리고 2) 적절한 역할을 제공하라는 이 성공 기준의 요구사항.
즉 아이콘 상태는 대체 텍스트(1.1.1) + 역할(4.1.3)이 함께 있어야 완성됩니다. 어느 한쪽만 있으면 전달이 안 돼요. 대체 텍스트만 있고 라이브 영역이 아니면 바뀌어도 조용하고, 라이브 영역인데 아이콘에 대체 텍스트가 없으면 알림이 울려도 내용이 비어 있으니까요.
<!-- 라이브 영역은 미리 두고 -->
<span role="status" id="save-state"></span>const saveState = document.getElementById('save-state');
// 저장 시작 — 아이콘은 장식(aria-hidden), 의미는 텍스트가 진다
saveState.innerHTML =
'<svg class="spinner" aria-hidden="true">…</svg>' +
'<span class="sr-only">저장 중…</span>';
// 저장 완료
saveState.innerHTML =
'<svg class="check" aria-hidden="true">…</svg>' +
'<span class="sr-only">저장됨</span>';숨은 텍스트 대신 <img alt="저장됨">처럼 대체 텍스트를 실어도 됩니다. 어느 쪽이든 스크린 리더는 “저장 중…”, “저장됨"을 읽게 돼요.
소리는 한 겹 더 조심해야 합니다. 알림음"만"으로 전달되는 상태는 청각 장애가 있는 사용자에게 닿지 않고, 스크린 리더 사용자에게도 그 소리가 무슨 뜻인지 알려주지 않습니다. 그러니 소리는 어디까지나 보조 신호로 쓰고, 같은 정보를 텍스트 상태 메시지로 함께 제공해야 해요. 데모 4번에 아이콘만 교체하는 버전과, 아이콘+숨은 텍스트+알림음을 조합한 버전을 나란히 뒀습니다.
설문의 새 질문은 왜 상태 메시지가 아닐까#
스터디에서 나온 마지막 질문입니다. 만족도 설문에서 “불만족"을 고르면 추가 질문이 화면에 나타나는 UI, 이 변화도 알려야 할까요? 답부터 말하면 알릴 의무는 없습니다. Understanding 문서에 정확히 이 예시가 있길래 원문을 확인해봤습니다. “상태 메시지가 아닌 변화의 예” 절에 이렇게 적혀 있어요.
사용자가 불만족을 표시하는 설문 문항에 답하자, 고객 만족에 관한 일련의 새 질문들이 페이지에 추가된다. 이 새 입력들은 상태 메시지의 정의를 충족하지 않는다. “행동의 성공이나 결과, 애플리케이션의 대기 상태, 프로세스의 진행 상황, 오류의 존재에 관한 정보"를 제공하지 않으므로, 이 성공 기준을 충족할 필요가 없다.
사실이 맞았습니다. 새 질문이 나타나는 건 성공도 대기도 진행도 오류도 아니니까, 정의의 관문을 통과하지 못하고 4.1.3의 대상이 아닙니다. 추가 질문을 조용히 넣어도 이 기준의 위반은 아니에요.
앞서 본 “초점을 받는 변화인가"까지 합치면, 판별은 아래처럼 두 관문을 통과하는 순서가 됩니다.

다만 “위반이 아니다"와 “이대로 충분하다"는 다른 문제죠. 스크린 리더 사용자 입장에서는 라디오 버튼 하나 골랐을 뿐인데 아래에 질문이 생긴 걸 모른 채 제출 버튼으로 직행할 수 있으니까요. 마침 Understanding 문서가 이 설문 예시 바로 뒤에 모범 사례를 달아뒀습니다.
이 질문들이 추가되었다는 상태 메시지를 만드는 것, 또는 사용자의 응답에 따라 콘텐츠 변화가 있을 수 있음을 미리 알리는 것은 모범 사례(best practice)다. 다만 이 시나리오에서 요구사항은 아니다.
선택지를 정리하면 이렇습니다.
- 조용히 추가한다. 기준 위반이 아니므로 그대로 둬도 됩니다. 새 질문이 현재 위치 바로 다음의 자연스러운 읽기 순서에 들어간다면, 사용자가 계속 진행하면서 자연스럽게 만나게 돼요.
- 답변 선택지에 미리 적어둔다. “아니오(선택 시 추가 질문 2개가 이어집니다)“처럼 선택지 라벨에 예고를 붙입니다. 위 인용이 말하는 “미리 알리기"를 바로 그 자리에서 해결하는 방법이에요. 변화가 일어나기 전에 알게 되니, 알림을 따로 만들 필요 자체가 없어집니다.
- polite로 한 줄 안내한다. “추가 질문 2개가 아래에 표시되었습니다” 같은 짧은 안내를
role="status"영역에 넣는 사후 방식입니다. Understanding 문서도 상태 메시지가 아닌 변화에 라이브 영역을 쓰는 것 자체는 사용자 경험을 높일 수 있다고 언급합니다. 단, 수다스러워지지 않는 선에서요. - 초점을 옮긴다. 이건 신중해야 합니다. 라디오 선택 같은 입력 도중에 초점을 강제로 옮기는 건 사용자가 예상하지 못한 맥락 변화가 되기 쉽고, 오히려 다른 성공 기준(3.2.2 입력 시)과 충돌할 수 있어요. 새 질문이 사용자의 명시적 행동(버튼 클릭 등)의 직접 결과일 때가 아니라면 권하지 않습니다.
제 선택은 2번, 미리 적어두기입니다. 사후의 polite 알림은 특성상 유실될 수 있지만, 라벨에 적힌 예고는 선택하는 순간 반드시 함께 읽히거든요. 비용은 괄호 한 줄이고요. 데모 5번에서 세 방식을 전환해가며 차이를 들어볼 수 있습니다.
한 장 요약#
- WCAG 4.1.3: 성공·대기·진행·오류를 알리는 콘텐츠 변화는 초점을 주지 않고도 스크린 리더가 읽을 수 있게
role/속성으로 판별 가능해야 합니다(AA). - 기본은
role="status"(polite): 하던 말이 끝난 뒤 읽습니다.assertive(role=“alert”)는 하던 말을 끊으므로 정말 시급한 오류에만. - 연속 업데이트는 디바운스: 화면 숫자는 즉시, 발화는 행동이 멈춘 뒤 최종값 한 번. 라이브 영역은 DOM에 미리 있어야 합니다.
- 아이콘·소리 상태: 대체 텍스트(1.1.1)와 역할(4.1.3)이 함께 있어야 전달됩니다. 소리만으로는 안 됩니다.
- 새로 나타나는 입력·질문: 상태 메시지가 아니므로 4.1.3 요구 대상이 아니지만, “아니오(선택 시 추가 질문 이어짐)“처럼 선택지에 미리 적어두는 것이 문서가 권하는 모범 사례입니다.
질문으로 다시 보기#
aria-live polite와 assertive는 무엇이 다른가요?
role='status'를 쓰면 aria-live를 따로 붙여야 하나요?
aria-live를 붙였는데 스크린 리더가 읽지 않아요. 왜 그런가요?
장바구니 개수처럼 연속으로 바뀌는 값은 어떻게 알리는 게 좋나요?
설문에서 답변에 따라 새 질문이 추가되면 상태 메시지로 알려야 하나요?
마치며#
4.1.3은 문장 하나짜리 짧은 기준이지만, 파고들수록 “얼마나 알릴 것인가"라는 설계 질문으로 이어집니다. 하나도 안 알리면 조용한 실패고, 전부 알리면 수다스러운 실패예요. 그 사이 어딘가의 적정선은 표준 문서가 아니라 실제 사용자의 귀로 확인할 수밖에 없습니다. 오늘 만든 데모, 스크린 리더를 켜고 한 번씩 눌러보시길 권해요. polite의 줄서기와 assertive의 끼어들기를 귀로 들어보면 다시는 안 헷갈리게 됩니다.
그리고 이런 질문들을 함께 파볼 사람들이 필요하다면 — 화요일 저녁, a11ykr이 있습니다.
참고 자료
