Enter The Dragon (Drop): 액세스 가능 목록 재정렬

게시 됨: 2022-03-10
빠른 요약 ↬ 현재 수많은 끌어서 놓기 목록 재정렬 모듈이 있지만 그 중 접근성을 염두에 두고 구축된 모듈은 거의 없습니다. Dragon Drop은 모든 사용자가 이 다소 일반적인 작업을 수행할 수 있는 수단을 제공하여 이 격차를 메우려고 합니다.

접근성에 중점을 둔 웹 개발자로서 수년 동안 저는 AT(보조 기술)로 잘 지원되는 널리 채택되고 표준화된 UI 구성 요소를 주로 처리했습니다. 이러한 유형의 위젯에는 접근성 문제에 대해 웹 구성 요소를 테스트하는 데 사용할 수 있는 axe-core와 같은 훌륭한 도구뿐만 아니라 간결한 ARIA 작성 방법이 있습니다. 덜 일반적인 위젯, 특히 사용자 상호 작용에 대해 널리 채택된 규칙이 없는 위젯을 만드는 것은 매우 까다로울 수 있습니다.

내가 만난 가장 어려운 문제 중 하나는 재정렬 가능한 끌어서 놓기 목록입니다. 재정렬 가능한 목록은 마우스 사용자를 위한 직관적인 규칙과 함께 다소 일반적으로 사용되는 위젯이지만 키보드 전용 보조 기술 사용자가 이 간단한 작업을 수행할 수 있는 방법은 명확하지 않습니다. 지원되는 ARIA 속성이 없기 때문에 Dragon Drop은 라이브 영역을 활용하여 모든 사용자가 목록을 재정렬하는 데 필요한 정보를 전달합니다.

라이브 지역

라이브 영역은 콘텐츠 변경 사항을 스크린 리더에 알리는 데 사용할 수 있는 ARIA 속성이 있는 HTML 요소입니다. 포커스를 이동하지 않고도 완전히 맞춤화된 스크린 리더 발표를 제공할 수 있습니다! 라이브 영역은 페이지의 원격 부분에서 실시간 업데이트, 상태 업데이트 및 시간에 민감한 정보에 적합합니다.

채팅 로그, 진행률 표시기, 스포츠 점수 업데이트 및 날씨 알림에 일반적으로 사용되지만 스크린 리더 사용자에게 지나치게 장황한 환경을 쉽게 만들 수 있으므로 드물게 사용해야 합니다. 라이브 지역을 처음 접하거나 그들이 할 수 있는 일을 탐색하고 싶다면 내 라이브 지역 플레이그라운드를 확인하여 자신만의 맞춤형 라이브 지역을 구성할 수 있습니다.

점프 후 더! 아래에서 계속 읽기 ↓

애플리케이션에서 라이브 영역을 사용하려면 npm의 라이브 영역 모듈을 참조하십시오.

 <div aria-live="assertive" role="log" aria-relevant="additions" aria-atomic="true"></div>

라이브 지역을 사용하는 이유

이상적인 세계에서는 드래그 앤 드롭 ARIA 속성 aria-grabbed -grabbed 및 aria-dropeffect 에만 의존할 수 있었습니다. 그러나 실제로 이러한 속성에 대한 지원은 드물며 지원되는 경우 화면 판독기 사용자에게 혼란스럽고 직관적이지 않습니다. 게다가 이 두 속성은 ARIA 1.1부터 더 이상 사용되지 않습니다. 즉, 앞으로 이러한 속성에 대한 지원이 증가하지 않을 것입니다.

이 지원 중단에 대한 W3C 대화는 여기에서 찾을 수 있습니다. 이러한 문제 때문에 Dragon Drop에서 aria- aria-grabbedaria-dropeffect 를 사용하지 않기로 결정했습니다. 광범위한 보조 기술/브라우저 페어링 내에서 ARIA 속성에 대한 다양한 지원은 접근성의 세계에서 상당히 널리 퍼져 있습니다. 운 좋게도 role , aria-live , aria-relevantaria-atomic 과 같은 라이브 지역 속성은 JAWS, NVDA 및 VoiceOver와 같은 화면 판독기에서 상당히 광범위하게 지원됩니다.

최적화된 접근성

Dragon Drop은 마우스, 키보드 및 보조 기술 사용자를 위해 작동하는 고도로 구성 가능한 목록 재정렬 모듈입니다. 몇 년 전, 내가 그것을 작성하기로 결정했을 때, 내가 작업하고 있던 프로젝트에 접근 가능한 재정렬 목록이 여러 번 제기되었지만 아직 작동하는 솔루션을 보지 못했습니다. 내가 만난 수십 개의 드래그 앤 드롭 목록 재정렬 플러그인 중 대부분은 접근성을 염두에 두고 설계되지 않았기 때문에 액세스가 매우 어려웠습니다.

Dragon Drop은 VoiceOver, JAWS 및 NVDA로 테스트되었으며 AT 사용자가 목록을 성공적으로 재정렬할 수 있습니다.

나는 모든 사용자가 재정렬 가능한 목록을 접했을 때 가질 수 있는 모든 질문에 답하기 시작했습니다. 이러한 질문은 일반적인 규칙을 통해 시력이 있는 마우스 사용자에 대한 답변이지만 나머지 사용자는 어떻습니까?

아이템을 어떻게 픽업할 수 있나요?

일부 최상위 도움말 텍스트와 함께 항목의 움켜진 상태를 전달하는 컨트롤을 제공하여 이 질문에 답할 수 있습니다. 예를 들어, 액세스 가능한 텍스트(AT에 의해 수집된 이름, 역할 및 값)가 있는 컨트롤 "Reorder Item 1, toggle button"은 활성화될 때 항목을 선택하고 시작하는 버튼임을 사용자에게 알려줍니다. 재정렬.

Dragon drop은 aria-pressed 속성을 사용하여 AT 사용자에게 항목이 "끌어지는" 때와 그렇지 않은 때를 알립니다. 전체 항목을 드래그할 수 있도록 구성하거나 하위 "드래그 핸들"만 허용하도록 구성할 수 있습니다. 두 경우 모두 role="button"tabindex="0" 의 존재가 보장됩니다.

드래그 항목이 활성화되면 aria-pressed="true" 가 요소에 적용되고 "항목 1 잡았습니다" 와 같은 구성 가능한 안내가 라이브 영역을 통해 스크린 리더에 읽혀집니다.

항목을 어떻게 이동할 수 있습니까?

"재정렬 버튼을 활성화하고 화살표 키를 사용하여 목록을 재정렬하거나 마우스를 사용하여 드래그/재정렬" 과 같은 유용한 도움말 텍스트와 컨트롤을 연결하기 위해 aria-describedby 활용 사용자에게 실제로 재정렬하는 방법을 알려줍니다. 이를 통해 스크린 리더 사용자는 항목을 눌렀을 때 위쪽 및 아래쪽 화살표 키가 항목을 각각 목록 위아래로 이동한다는 것을 알 수 있습니다.

아이템을 어떻게 떨어뜨릴 수 있나요?

aria-pressed 속성을 사용하기 때문에 사용자는 아이템을 드롭하는 방법을 쉽게 알 수 있습니다. 어떤 방식으로든 모양이나 형태에서 가장 널리 사용되는 모든 스크린 리더는 토글 버튼의 ​​눌린 상태를 전달합니다. aria-pressed 속성은 아이템이 드롭될 때 "false"로 설정되고 "Item 1 drops" 와 같은 사용자 정의 알림이 스크린 리더로 읽혀집니다.

목록이 재정렬되었는지 어떻게 알 수 있습니까?

위쪽 및 아래쪽 화살표 키를 사용하여 목록의 순서를 변경할 때마다 모든 사용자에게 이 변경 사항을 알려야 합니다. 시력이 없는 사용자의 경우 다시 한 번 라이브 지역에 의존해야 합니다. "목록이 재정렬되었습니다. 항목 1은 이제 목록에서 4번째입니다." 와 같은 구성 가능한 안내문. , 재정렬된 목록의 업데이트된 상태를 전달하기 위해 읽습니다. 이는 시력 사용자가 변경된 순서에 대해 즉각적인 시각적 피드백을 받고 AT 사용자에게 동일한 정보를 전달해야 하기 때문에 중요합니다.

재주문을 취소하려면 어떻게 합니까?

이러한 상호 작용에 대해 널리 채택된 규칙에 의존할 수 없기 때문에 도움말 텍스트에 "재주문을 취소하려면 이스케이프를 누르십시오" 와 같은 지침을 간단히 포함할 수 있습니다. 또한 라이브 지역을 활용하여 사용자에게 취소를 알리는 맞춤형 판독값을 제공합니다.

키보드 상호 작용

열쇠 행동
Enter 또는 공백 "잡은" 상태와 "떨어진" 상태 사이에서 항목을 전환합니다.
"↓" 목록에서 "잡은" 항목을 아래로 이동합니다.
"↑" 목록에서 "잡은" 항목을 위로 이동합니다.
ESC 재주문을 취소하고 초기 주문을 복원합니다.

드래곤이 작동하는 모습 보기

몇 가지 다른 구성을 경험하는 Dragon Drop 데모를 확인하십시오.

드래곤 드롭을 앱에 떨어뜨리기

Dragon Drop은 일반 목록을 완전히 액세스 가능한 드래그 앤 드롭 재정렬 가능한 목록으로 변환합니다.

 <ul> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> </ul> <script> const dragon = document.getElementById('dragon'); // Enter the dragon new DragonDrop(dragon); </script>

설치

Dragon Drop은 오픈 소스(MIT 라이선스) 프로젝트이며 npm을 통해 설치할 수 있습니다.

 $ npm install drag-on-drop

browserify 또는 webpack과 같은 모듈과 함께 사용할 수 있습니다.

 // if you're not down with ES6, you can require('drag-on-drop') import DragonDrop from 'drag-on-drop';

Dragon Drop은 unpkg CDN을 사용하여 페이지에 쉽게 드롭할 수도 있습니다.

 <script source="https://unpkg.com/drag-on-drop"></script> <script> var dragonDrop = new DragonDrop(listElement); </script>

구성

다양한 사용 사례를 지원하기 위해 Dragon Drop은 매우 구성 가능합니다.

다음은 기본 구성입니다.

 { item: 'li', handle: 'button', activeClass: 'dragon-active', inactiveClass: 'dragon-inactive', announcement: { grabbed: el => `Item ${el.innerText} grabbed`, dropped: el => `Item ${el.innerText} dropped`, reorder: (el, items) => { const pos = items.indexOf(el) + 1; const text = el.innerText; return `The list has been reordered, ${text} is now item ${pos} of ${items.length}`; }, cancel: 'Reordering cancelled' } }

공지사항

Dragon Drop의 "공지" 구성 옵션은 Dragon Drop이 제공하는 스크린 리더 경험의 중추이기 때문에 가장 중요합니다. "grabbed" , "dropped" , "reorder""cancel" 기능을 포함하는 개체로 발생하는 모든 상호 작용에 대한 사용자 지정 라이브 지역 공지를 허용합니다.

이러한 각 함수는 지정된 작업이 발생할 때 라이브 영역에 추가되는 안내 텍스트 문자열을 반환해야 합니다. 이러한 기능을 활용하는 추가 이점은 라이브 지역 메시지의 현지화를 지원한다는 것입니다.

공지 사항을 용이하게 하기 위해 작업이 발생한 목록 항목 요소와 목록의 항목 배열이 각각 인수로 전달됩니다.

 { announcement: { // grabbed is called when an item is picked up grabbed: (targetItem, items) => `${targetItem.innerText} grabbed`, // dropped is called when an item is dropped dropped: (targetItem, items) => `${targetItem.innerText} grabbed`, // reorder is called each time the order of the list is altered reorder: (targetItem, items) => { return `${targetItem.innerText} is now ${items.indexOf(targetItem) + 1} of ${items.length}` }, // cancel is called when a reordering is cancelled (via escape key) cancel: () => 'The initial order has been restored, reordering cancelled' } }

도움말 텍스트

재정렬 가능한 목록을 사용하는 방법을 설명하는 도움말 텍스트를 제공하는 것이 절대적으로 중요합니다. 이것은 이 텍스트를 보조 기술에 사용할 수 있도록 하는 방법에 대해 덜 독단적인 태도를 유지하기 위해 Dragon Drop이 귀하를 위해 하지 않는 것입니다. 권장되는 구현은 다음과 같이 도움말 텍스트를 대화형 항목과 연결하기 위해 aria-describedby 를 사용하는 것입니다.

 <p>Activate the reorder button and use the arrow keys to reorder the list or use your mouse to drag/reorder. Press escape to cancel the reordering.</p> <ul> <li> <button>Reorder Item 1</button> <span>Item 1</span> </li> <li> <button>Reorder Item 2</button> <span>Item 2</span> </li> <li> <button>Reorder Item 3</button> <span>Item 3</span> </li> </ul>

GitHub의 드래곤 드롭

Dragon Drop의 세 번째 버전이 최근에 출시되었습니다. 사용에 관심이 있으시면 GitHub의 Dragon Drop 설명서를 참조하십시오. Dragon Drop이 마우스 상호 작용에 사용하는 모듈인 Dragula의 제작자와 멋진 로고를 디자인한 Aaron Pearlman에게 특별한 감사를 드립니다!

용의 미래

향후 WAI-ARIA 기술 사양에 드래그 앤 드롭 상호 작용이 추가되면 Dragon Drop이 비표준 상호 작용 및 라이브 영역에 의존한다는 사실이 변경될 수 있습니다. 가능한 한 많은 스크린 리더가 지원하는 상태를 유지하고 최신 ARIA 사양을 유지하도록 테스트를 계속 수행할 것입니다. 또한, 터치 스크린/모바일 장치 및 다중 열 목록(예: 스프린트 보드)에 대한 지원을 포함하여 파이프라인에 꽤 많은 기능이 있습니다. 앞으로 추가될 수 있는 또 다른 기능은 Dragon Drop React 구성 요소입니다.

CodePen에서 Harris Schneiderman(@schne324)의 Pen React Dragon Drop을 참조하십시오.

CodePen에서 Harris Schneiderman(@schne324)의 Pen React Dragon Drop을 참조하십시오.

현재 Dragon Drop은 아래 데모에 표시된 것처럼 React와 함께 사용할 수 있지만 목록 재정렬로 인한 DOM 변경 사항이 React에서 선택되지 않아 예기치 않은 동작이 발생할 수 있으므로 이상적이지 않습니다. Dragon Drop에서 버그를 찾거나 GitHub에서 문제를 생성할 기능에 대한 아이디어가 있는 모든 사람에게 촉구합니다. 모든 피드백과 기여를 환영하며 대단히 감사합니다!