사전 라이브 리전
표준

라이브 리전

gabury1고친 사람 github-actions[bot]

라이브 리전은 웹 페이지 한 구역의 내용이 바뀌면 그 새 내용을 화면 읽어 주는 프로그램이 알아서 읽게 합니다. 사용자가 그 구역으로 옮겨 가지 않아도 됩니다. 「장바구니에 담았습니다」 같은 알림을 화면을 못 보는 사용자에게도 전하려고 씁니다.

쉽고 빠른 이해

라이브 리전은 저절로 바뀌는 화면 구역을 귀로도 들리게 합니다. 담기 버튼을 누른 뒤 뜨는 「장바구니에 담았습니다」를 사용자가 버튼에 머문 채로 듣는 식입니다.

화면을 읽어 주는 프로그램은 사용자가 지금 가 있는 곳만 읽습니다. 그래서 다른 곳에서 일어난 변화는 놓칩니다. 화면에는 알림이 떴는데 귀로 듣는 사용자는 아무 일도 없었다고 여깁니다.

  1. 알림이 뜰 상자에 aria-live="polite"(읽던 말을 마친 뒤에 알려 달라는 표시)를 미리 붙여 둡니다
  2. 코드가 그 상자에 글자를 넣습니다
  3. 브라우저가 바뀐 것을 알립니다. 읽어 주는 프로그램이 그 글자를 읽습니다

대가는 듣는 사람의 귀를 빼앗는다는 것입니다. 너무 자주 알리면 사용자가 하던 일을 못 따라갑니다. 급하다고 끼어들게 하면 듣던 말이 끊깁니다.

상세

이 절은 알림 상자 하나를 따라갑니다. 먼저 이런 상자가 왜 따로 필요한지 봅니다. 이어서 상자에 붙이는 속성과 그 값이 귀에 닿기까지의 흐름을 봅니다. 끝으로 무엇을 읽힐지 고르는 속성과 흔한 실수를 모읍니다.

화면을 못 보는 사용자가 놓치는 변화

보조 기술은 장애가 있는 사용자가 컴퓨터를 쓰도록 돕는 소프트웨어와 기기입니다. 그중 스크린 리더는 화면의 글과 부품을 소리나 점자로 읽어 줍니다. 사용자는 키보드로 부품 사이를 옮겨 다닙니다. 옮겨 간 곳에서 「담기, 버튼」 같은 안내를 듣습니다.

키보드 입력을 받을 차례가 된 부품을 포커스를 받았다고 합니다. 스크린 리더는 대개 포커스가 온 부품을 읽습니다. 사용자의 귀는 언제나 한 곳에 가 있는 셈입니다.

문제는 포커스와 먼 곳이 바뀔 때입니다. 담기 버튼을 누르면 화면 위쪽에 「장바구니에 담았습니다」가 뜹니다. 포커스는 버튼에 그대로 있으니 스크린 리더는 그 글을 읽지 않습니다.

라이브 리전은 이 틈을 메웁니다. 「이 구역이 바뀌면 사용자가 어디 있든 알려 달라」고 미리 표시해 두는 구역입니다. 채팅 메시지, 입력 오류, 검색 결과 수처럼 사용자가 안 건드렸는데 바뀌는 글이 대상입니다.

aria-live 로 구역을 표시하기

웹 페이지는 HTML(HyperText Markup Language)이라는 언어로 씁니다. HTML 은 <div> 같은 태그로 페이지의 부품을 나눕니다. 태그 안에는 id="msg" 처럼 속성을 적어 그 부품에 정보를 덧붙입니다.

라이브 리전은 ARIA(Accessible Rich Internet Applications)가 정한 방법입니다. ARIA 는 HTML 태그에 속성을 더 붙여서 보조 기술에 전할 정보를 바꾸는 표준입니다.

구역을 표시하는 속성이 aria-live 입니다. 태그에 이 속성을 붙이면 그 태그와 안에 든 것이 라이브 리전이 됩니다.

HTML
<div id="msg" aria-live="polite"></div>

이 상자는 처음에 비어 있습니다. 나중에 자바스크립트가 글자를 넣으면 스크린 리더가 그 글자를 읽습니다. 아래 코드의 msg 는 위에서 id="msg" 로 둔 그 상자입니다. 오른쪽 주석은 스크린 리더가 읽는 말입니다.

JavaScript
msg.textContent = '담았어요'; // 담았어요

사용자의 포커스는 담기 버튼에 머물러 있습니다. 그래도 「담았어요」를 듣습니다.

끼어드는 정도를 고르는 값

aria-live 의 값은 스크린 리더가 언제 읽을지를 정합니다. 값은 셋입니다.

값 언제 읽나 어울리는 글
off 알리지 않는다. 적지 않았을 때와 같다 사용자가 직접 찾아가 읽을 글
polite 지금 읽던 말을 마친 뒤에 저장 완료 · 검색 결과 수 · 새 채팅
assertive 읽던 말을 끊고 바로 세션 만료 직전 · 결제 실패

polite 는 사용자가 듣던 것을 존중합니다. 대부분의 알림은 이 값으로 충분합니다.

assertive 는 듣던 말을 자릅니다. 사용자는 끊긴 앞말을 놓치고 다시 찾아 들어야 합니다. 그래서 지금 알지 못하면 손해를 보는 알림에만 씁니다.

바뀐 글이 귀에 닿기까지

스크린 리더는 화면에 그려진 그림을 보지 않습니다. 브라우저가 웹 문서의 부품을 나무 모양으로 따로 정리한 구조를 읽습니다. 이 구조가 접근성 트리입니다.

브라우저는 웹 문서를 먼저 DOM(Document Object Model)이라는 트리 구조로 읽습니다. 자바스크립트가 바꾸는 것도 이 DOM 입니다. 접근성 트리는 DOM 에서 사용자에게 전할 부품을 골라 세운 것이라 DOM 이 바뀌면 따라 바뀝니다.

라이브 리전 안의 DOM 이 바뀌면 브라우저가 한 가지를 더 합니다. 「이 구역이 바뀌었다」는 신호를 스크린 리더에 보냅니다. 신호를 받은 스크린 리더는 aria-live 값에 따라 읽을 때를 정합니다.

sequenceDiagram
    participant 코드 as 자바스크립트
    participant DOM
    participant 브라우저
    participant 리더 as 스크린 리더
    코드->>DOM: 라이브 리전에 글자를 넣는다
    DOM->>브라우저: 내용이 바뀌었다
    브라우저->>브라우저: 접근성 트리를 고친다
    브라우저->>리더: 라이브 리전이 바뀌었다는 신호
    Note over 리더: polite 면 읽던 말을 마치고 assertive 면 바로
    리더->>리더: 새 글을 읽는다

글자를 넣고 접근성 트리를 고치는 데까지는 라이브 리전이 아니어도 똑같이 일어납니다. 라이브 리전이 더하는 것은 「라이브 리전이 바뀌었다」는 신호 하나입니다. 이 신호가 없으면 접근성 트리는 바뀌어도 스크린 리더가 읽으러 오지 않습니다.

역할로 정해 두는 라이브 리전

role 은 그 태그가 무슨 부품인지 보조 기술에 알리는 ARIA 속성입니다. 몇몇 역할은 붙이기만 해도 라이브 리전이 됩니다. aria-live 를 따로 적지 않아도 그 역할에 맞는 값이 정해져 있습니다.

역할 무엇에 쓰나 정해진 aria-live
alert 급한 경고 · 오류 assertive
status 진행 상태 · 완료 안내 polite
log 채팅 · 기록처럼 아래로 쌓이는 글 polite
timer 남은 시간처럼 계속 바뀌는 수 off
marquee 뉴스 띠처럼 흘러가는 글 off

timer 와 marquee 가 off 인 까닭은 바뀌는 빈도에 있습니다. 1초마다 바뀌는 수를 1초마다 읽으면 사용자는 다른 것을 아무것도 못 듣습니다. 이런 구역은 사용자가 원할 때 찾아가 읽습니다.

HTML 에도 처음부터 라이브 리전인 태그가 있습니다. 계산 결과를 보여 주는 `<output>` 태그는 status 역할을 가집니다. 맞는 태그가 있으면 역할을 손으로 적기보다 그 태그를 씁니다.

무엇을 읽을지 고르는 속성

구역의 일부만 바뀔 때 스크린 리더가 바뀐 조각만 읽을지 구역 전체를 읽을지가 갈립니다. 이것을 aria-atomic 이 정합니다.

장바구니 개수를 보여 주는 문장으로 봅니다. 숫자만 <span> 태그에 따로 담고 id="n" 을 붙였습니다.

HTML
<p aria-live="polite">
  장바구니 <span id="n">2</span>개
</p>

아래 코드의 n 이 그 <span> 입니다. 숫자만 바꿔 봅니다. 오른쪽 주석은 aria-atomic 값에 따라 스크린 리더가 읽는 말입니다.

JavaScript
// aria-atomic 을 안 적었을 때
n.textContent = '3'; // 3
// aria-atomic="true" 일 때
n.textContent = '3'; // 장바구니 3개

기본값은 바뀐 조각만 읽습니다. 「3」만 들으면 무엇이 3인지 알 수 없습니다. 조각만으로 뜻이 안 서는 구역에는 aria-atomic="true" 를 붙여 문장 전체를 읽게 합니다. 앞 소절의 alert 와 status 는 처음부터 전체를 읽도록 정해져 있습니다.

aria-relevant 는 어떤 변화를 알릴지 고릅니다. 기본은 글자가 새로 붙거나 바뀔 때만 알립니다. 지워진 것까지 알리게 할 수 있지만 쓸 일이 드뭅니다.

aria-busy 는 「지금 고치는 중이니 기다려 달라」는 표시입니다. 여러 곳을 차례로 고칠 때 true 로 두었다가 다 고친 뒤 false 로 돌립니다. 그러면 스크린 리더가 고치는 도중에는 읽지 않고 다 고친 결과를 한 번에 읽습니다.

상자를 먼저 놓고 나중에 채운다

가장 흔한 실수는 라이브 리전을 글자와 함께 한꺼번에 페이지에 넣는 것입니다. 이러면 대개 읽히지 않습니다. 스크린 리더는 이미 지켜보던 구역의 변화를 알리는 것이지 새로 생긴 구역을 알리는 것이 아닙니다.

그래서 빈 상자를 페이지가 처음 뜰 때부터 둡니다. 알릴 일이 생기면 그 상자의 글자만 바꿉니다. 오른쪽 주석은 각 방식의 결과입니다.

JavaScript
// 글자가 든 상자를 새로 붙인다
document.body.append(box); // 대개 침묵
// 미리 둔 빈 상자에 글자를 넣는다
msg.textContent = '저장됨'; // 저장됨

상자를 감출 때도 조심해야 합니다. 감추는 방법에 따라 상자가 접근성 트리에 남느냐 빠지느냐가 갈립니다. 빠진 상자는 글자가 바뀌어도 읽히지 않습니다.

빠지는 쪽은 둘입니다. 화면 모양을 정하는 언어인 CSS(Cascading Style Sheets)로 display: none 을 주면 상자가 화면에서도 접근성 트리에서도 사라집니다. aria-hidden 을 true 로 두면 화면에는 그대로 두고 보조 기술에만 감춥니다.

남는 쪽은 시각적 숨김입니다. 상자를 화면 밖으로 밀어내 눈에만 안 보이게 하는 방법입니다. 태그와 글자는 그대로 있어서 접근성 트리에 남습니다. 눈에는 안 보이고 귀로만 들려야 하는 안내에 이 방법을 씁니다.

쓰는 때와 안 쓰는 때

상황별로 모으면 아래와 같습니다.

상황 쓰는 것
저장 완료 · 검색 결과 수 · 새 메시지 aria-live="polite" 나 role="status"
입력을 다시 해야 하는 오류 · 곧 끊기는 세션 role="alert"
채팅 창처럼 아래로 쌓이는 기록 role="log"
1초마다 바뀌는 시계 · 진행률 숫자 알리지 않는다. 다 끝났을 때만 한 번 알린다
사용자가 직접 연 메뉴 · 대화상자 라이브 리전 대신 포커스를 그쪽으로 옮긴다

마지막 줄은 라이브 리전과 포커스 이동을 가르는 기준입니다. 사용자가 다음에 그곳에서 무언가를 해야 하면 포커스를 옮깁니다. 듣기만 하고 하던 일을 이어 가면 되면 라이브 리전으로 알립니다.

라이브 리전으로 읽힌 말은 한 번 지나가면 사라집니다. 사용자가 놓쳤을 때 다시 들을 길이 마땅치 않습니다. 그래서 오래 남아야 할 정보는 알림과 별개로 페이지 안에 글로도 남겨 둡니다.

제대로 읽히는지 확인하기

라이브 리전은 화면을 안 바꾸니 눈으로는 확인할 수 없습니다. 실제 스크린 리더를 켜고 그 동작을 해 보는 것이 가장 확실합니다. 스크린 리더마다 읽는 방식이 조금씩 달라서 하나로만 듣고 끝내지 않습니다.

브라우저 개발자 도구의 접근성 패널에서는 그 구역에 붙은 aria-live 값과 역할을 볼 수 있습니다. 상자가 처음부터 페이지에 있는지, 감춰져 있지 않은지도 봅니다.

관련 항목

라이브 리전이 속하는 상위 분류와 표준

ARIA · 접근성 · 웹 접근성 · WCAG · W3C · HTML

라이브 리전을 만들고 다듬는 ARIA 속성

aria-live · aria-atomic · aria-relevant · aria-busy · aria-hidden · aria-label

라이브 리전이 되는 역할과 태그

role · alert 역할 · status 역할 · log 역할 · timer 역할 · marquee 역할 · output 요소

라이브 리전의 변화가 지나가는 구조

DOM · 접근성 트리 · 접근성 API · 브라우저 · 자바스크립트

라이브 리전으로 알리는 화면 부품

토스트 · 알림 · 폼 검증 · 채팅 · 진행 표시줄 · SPA

라이브 리전 대신 쓰는 알림 수단

포커스 · 포커스 관리 · 모달 대화상자 · 시각적 숨김

라이브 리전의 알림을 받는 보조 기술

보조 기술 · 스크린 리더 · 점자 디스플레이 · 음성 제어

라이브 리전을 살피는 도구

개발자 도구 · Playwright · Testing Library · 자동 검사

다른 이름: live region · 라이브 영역 · aria-live 영역