아래 내용은 크롬 개발자 블로그에 2021년 10월 게시된 글입니다. 크롬 브라우저의 접근성 트리가 어떻게 동작하는지 가볍게 살펴보기 위해 번역했습니다. 아마도 이 글을 보는 것보다 이 글을 작성한 시점보다 좀 더 나아진 기계번역의 힘을 빌리는 것이 좀 더 좋은 방법이라 생각됩니다.
* 크로미움 접근성 관련해서는 아래 문서를 참고하세요.
https://chromium.googlesource.com/chromium/src/+/HEAD/docs/accessibility.md
* 원문에는 2개의 동영상이 추가되어 있는데 딱히 필요없는 영상이라 제외했습니다. 대신 전체 접근성 트리를 활성화하는 내용은 이미지 캡쳐로 대체했습니다.
Johan Bay
Googler working on Chrome DevTools.
https://github.com/johanbay
Published on Monday, December 13, 2021
https://developer.chrome.com/blog/full-accessibility-tree/
개발자가 크롬 개발자 도구에서 전체 접근성 트리를 쉽게 파악할 수 있게 전체 접근성 트리 기능을 출시했습니다. 이번 글에서 트리가 어떻게 생성되는지 그리고 여러분의 개발 작업에서 어떻게 활용할 수 있는지 알아보세요.
접근성 트리는 무엇인가요?
스크린 리더와 같은 보조 기술은 크로미움의 접근성 API를 사용해 웹콘텐츠와 상호 작용합니다. 접근성 API의 기본 모델은 접근성 트리입니다. 접근성 객체의 트리를 통해 보조 기술은 각 속성과 실제 속성값을 탐색하고 필요한 작업을 수행할 수 있습니다. 웹 개발자는 주로 HTML에서 ARIA 속성과 같은 DOM 속성값을 통해 접근성 트리를 만들고 이를 다룹니다.
크롬 개발자 도구에서는 개발자에게 콘텐츠가 보조 기술에 어떤 식으로 전달되는지 이해할 수 있게 접근성 창을 제공하고 있습니다. DOM 트리 뷰어에서 노드를 선택하면 해당하는 접근성 노드의 속성 정보가 상위 노드, 직계 자식 노드와 함께 창에 표시됩니다.
트리는 어떻게 만들어지나요?
개발자 도구에서 전체 트리 보기가 어떻게 보일 수 있는지 살펴보기 전에 접근성 트리가 무엇인지 좀 더 구체적으로 살펴보겠습니다. 접근성 트리는 DOM 트리에서 파생된 형태입니다. 구조는 거의 비슷하지만 스타일 처리를 위해 사용하는 의미가 없는 <div> 요소를 제거하고 단순하게 처리합니다. 트리의 각 노드는 Button이나 Heading 같은 role이 있으며 ARIA 속성이나 노드의 콘텐츠에서 가져온 name을 가지고 있습니다. HTML 문서를 잠시 살펴봅시다.
<html>
<head>
<title>How old are you?</title>
</head>
<body>
<label for="age">Age</label>
<input id="age" type="number" name="age" value="42">
<div>
<button>Back</button>
<button>Next</button>
</div>
</body>
</html>
Blink라는 이름을 가진 크로미움의 렌더러는 아래와 같은 형태로 내부 처리를 위한 트리를 생성합니다.
role='rootWebArea' focusable name='How old are you?'
role='genericContainer' ignored
role='genericContainer' ignored
role='labelText'
role='staticText' name='Age'
role='spinButton' editable focusable name='Age' value='42'
role='genericContainer' editable
role='staticText' editable name='42'
role='genericContainer'
role='button' focusable name='Back'
role='staticText' name='Back'
role='button' focusable name='Next'
role='staticText' name='Next'
여기에는 role이 genericContainer인 불필요한 노드가 여러 개 포함되어 있으며 접근성 트리가 DOM 트리의 단순한 파생물이라는 위의 설명과 맞지 않는 것처럼 보입니다. 하지만 이런 노드 대부분은 내부 트리에서만 처리되며 보조 기술에 노출되지는 않습니다. 개발자 도구는 렌더러 프로세스에서 직접 접근성 정보를 수집하기 때문에 개발자 도구가 처리하는 트리는 이런 형식이 됩니다.
개발자 도구에서 전체 접근성 트리
새로운 전체 접근성 트리는 DOM 트리와 동기화되어 개발자가 두 개의 트리 사이를 전환할 수 있습니다. 아마도 새로운 트리가 더 탐색하기 쉽고 유용하며 사용하기 쉬울 것으로 기대하고 있습니다.
* 개발자 도구에서 Elements 항목을 선택하고 오른쪽 창에서 Accessibility를 선택하면 "Enable full-page accessibility tree" 항목을 체크할 수 있습니다. 체크하면 HTML 코드가 있는 창 오른쪽 상단에 버튼 하나가 활성화됩니다.
전체 접근성 트리 기능이 출시된지 1년이 지났지만 아직 여전히 기본 기능이 되지는 않았네요.
이제 접근성 트리가 어떻게 작동하는지 가볍게 살펴보았으니 개발자 도구를 사용해 새로운 트리가 어떻게 보이는지 살펴봅시다. title, heading, 2개의 버튼을 가지는 HTML 문서를 살펴볼 겁니다.
<!DOCTYPE html>
<title>Test</title>
<h1>Heading for example page</h1>
<div>
<button>Back</button>
<button>Next</button>
</div>
이전 트리 보기에서는 단일 노드와 그 상위 노드만 탐색할 수 있었습니다.
새로운 트리 보기 기능으로 토글 하면 DOM 트리 보기 대신 전체 접근성 트리 보기로 전환됩니다.
게으른 트리 생성
대규모 사이트에서도 트리의 성능이 떨어지지 않게 트리 탐색 시 프런트엔드에서는 트리를 느리게 생성합니다. 트리에서 노드가 확장되면 해당 노드의 자식 노드가 크롬 개발자 도구 프로토콜(CDP)을 통해 정보를 가져와 트리를 다시 생성합니다.
실시간 처리
새로운 트리 보기는 실시간이며 렌더러에서 접근성 트리가 변경되면 동적으로 업데이트됩니다. 이는 보조 기술에 트리 변경 사항을 알리는 것과 같은 메커니즘이며 이를 사용해 업데이트된 노드가 있는 개발자 도구의 프런트엔드에 이벤트를 전송합니다. 실제 CDP 뒤편에서는 트리에 대한 업데이트 정보를 수신하고 이전에 요청된 노드를 추적하며 이런 노드 중 하나라도 변경되면 개발자 도구 프런트엔드로 이벤트를 전송합니다.
복잡한 트리 구조를 다루는 방식
접근성 트리가 무엇인지에 대한 설명을 통해 여러분은 Blink가 렌더링 되는 DOM에서 접근성 트리를 생성하고 개발자 도구가 CDP를 통해 트리 정보를 가져오는 방법을 배웠습니다. 정확한 설명이긴 하지만 몇 가지 복잡한 과정에 대한 설명은 생략했습니다. 실제 크롬에서 접근성 트리를 경험하는 방법은 매우 다양합니다. 개발자 도구의 새로운 트리 보기를 설계할 때 우리는 그 과정에서 크로미움이 내부에서 처리하는 접근성 기능 중 어떤 부분을 드러내고 싶은지 몇 가지 선택을 했습니다.
플랫폼
플랫폼마다 접근성 API가 다르며 트리의 모양은 모든 플랫폼에서 같지만 트리와 상호 작용하는 API가 다르며 속성의 이름도 다를 수 있습니다. 개발자 도구는 role과 속성이 ARIA 사양에 정의된 것과 어느 정도 일치하는 내부 트리를 보여줍니다.
여러 프레임에서 서로 다른 사이트 처리하기
크로미움은 모든 탭에 표시된 콘텐츠를 서로 다른 렌더링 프로세스로 배치하고 사이트 간 문서를 서로 다른 렌더링 프로세스로 격리합니다. 때문에 CDP를 통해 프로세스뿐 아니라 각 하위 문서에 개별적으로 연결해서 접근성 트리를 가져와야 합니다. 그런 다음 프런트엔드에서 이런 하위 트리를 함께 연결해 크로미움에서는 서로 다른 렌더러 프로세스에 있지만 하나의 일관된 트리처럼 보이게 합니다.
ignored로 체크된 노드
기본적으로 ignored로 체크된 노드와 name이 없고 "generic" role을 가진 노드는 숨겨집니다. 이런 노드는 의미를 가지고 있지 않으며 보조 기술에 노출되지 않습니다. 트리 보기가 복잡해지지 않게 이런 노드는 숨김으로 처리합니다. 그렇지 않으면 대부분의 웹페이지 접근성 트리는 다음과 같이 복잡하게 보일 겁니다.
여기서 주의할 점은 백엔드에서 사용할 수 있는 것과 다른 트리를 구성해야 한다는 것입니다. 예를 들어 노드 A, B, C, X가 있고 A에 자식 B, X가 있고 X는 자식 C를 가지고 있다고 가정합니다. X가 ignored 노드인 경우에는 트리에서 X를 제거하고 대신 C가 A의 자식인 트리로 생성됩니다.
프런트엔드에서는 ignored 상태의 노드를 포함한 전체 트리를 구성하고 노드 렌더링 직전에 가지치기를 합니다. 이렇게 하는 이유는 두 가지입니다.
- 두 개의 엔드포인트에 같은 트리 노드가 있으면 백엔드에서 노드 업데이트를 처리하는 것이 훨씬 간단해집니다. 예를 들어 위의 예시에서 노드 B가 제거되면 노드 X에 대한 업데이트가 수신되지만(자식이 변경되었으므로) 해당 노드를 가지치기한 상태에서는 무엇을 업데이트할지 파악하는데 어려움을 겪을 겁니다.
- 모든 DOM 노드에 해당 접근성 노드가 있는지 확인합니다. 트리가 토글 되면 DOM 트리에서 현재 선택한 노드에 해당하는 노드를 선택합니다. 따라서 앞의 예시에서 사용자가 X에 해당하는 DOM 노드를 선택한 상태에서 트리를 토글 하면 노드 A와 B 사이에 X를 삽입하고 트리에서 X를 선택합니다. 이를 통해 사용자는 모든 DOM 노드에 대한 접근성 노드를 검사하고 노드가 무시되는 이유를 파악할 수 있습니다.
향후 계획
새로운 접근성 트리를 출시하는 것은 이제 시작입니다. 새로운 보기를 기반으로 만들고자 하는 몇 가지 프로젝트에 대한 아이디어를 가지고 있습니다. 여러분의 의견도 기다리고 있습니다.
대체 필터링 옵션
위에서 설명한 것처럼 필요치 않은 노드는 필터링해서 숨김으로 처리하고 있습니다. 이런 동작을 비활성화하고 모든 노드를 표시할 수 있는 방법을 제공하거나 "Show landmark nodes"나 "Show headings" 같은 필터링 옵션을 제공할 수도 있습니다.
접근성 이슈 체크하기
"접근성 모범 사례" 정보를 통합해 문제가 있는 노드를 찾아 이에 대한 해결책을 제시할 수 있습니다.
개발자 도구에서 접근성 동작 다루기
현재 표시되는 트리는 단방향 정보입니다. 특정 웹 페이지를 탐색할 때 보조 기술에 어떤 정보가 제공되는지 파악하는 것입니다. 접근성 기능은 다른 방향의 커뮤니케이션을 포함하고 있습니다. 예를 들면 보조 기술의 UI에서 작동할 수도 있습니다. 개발자 도구에서 이런 액션을 표시해 보조 기술이 사용할 수 있는 API를 사용해 페이지에서 '클릭'이나 스크롤 또는 값 변경 같은 작업을 허용할 수 있습니다.