NARADESIGN

웹표준, 웹접근성, 유니버설디자인, HTML, CSS, UI, UX, UD


레이어 열기/닫기 키보드 접근성.

본문 건너 뛰기

일반적으로 레이어 열기/닫기 인터페이스는 다음과 같은 방식으로 처리하고는 하죠. 하지만 보통은 키보드 접근성 문제가 발생합니다.

통상적인 레이어 열기/닫기 예: http://codepen.io/naradesign/pen/eynbo

레이어 열기/닫기 UI의 키보드 접근성 문제

  1. 레이어가 열리는 순간 초점 순서 오류: 앵커를 클릭 또는 엔터를 입력한 이후에 키보드 초점은 여전히 앵커에 머물러 있습니다. 열린 레이어로 키보드 초점이 이동해야 하는데 인위적으로 초점을 옮겨주지 않으면 여전히 앵커에 초점이 머뭅니다. 열리는 레이어가 앵커 바로 다음에 등장하는 경우라면 순서에 문제가 없지만 앵커와 레이어가 서로 다른 위치에 존재하는 경우 인위적으로 초점을 옮겨주지 않으면 키보드 초점은 엉뚱한 곳을 탐색하게 되므로 오류에 빠지게 됩니다. 모든 브라우저가 이렇게 동작합니다.
  2. 레이어가 닫히는 순간 키보드 트랩: 열린 레이어를 닫으려고 레이어 닫기 버튼을 클릭하거나 엔터를 입력하면 레이어가 사라져 버리기 때문에 키보드 초점은 페이지 처음으로 돌아가 버리는 브라우저가 있습니다. IE 6~10 브라우저가 이렇게 동작합니다. 대부분의 표준 브라우저들은 닫힌 레이어 이후부터 키보드 초점을 받을 수 있도록 정상적으로 처리합니다.

레이어가 열리는 순간 초점 순서를 바로잡는 방법

키보드 초점을 논리적인 순서대로 진행하도록 만들기 위해 앵커 클릭 후 레이어가 열리는 순간 초점을 레이어로 옮기는 예시를 만들어 봤습니다.

앵커 클릭하면 레이어로 초점 옮기기: http://codepen.io/naradesign/pen/brwuj

  1. 앵커를 클릭하면 타겟 레이어에 tabindex=”0″ 속성이 들어가면서 초점을 받을 수 있는 상태가 된다.
  2. 레이어의 상태를 display:block 으로 만든다.
  3. 레이어에 focus를 넣는다.

이렇게 처리하면 앵커와 레이어 중간에 존재하는 엉뚱한 맥락의 다른 콘텐츠를 탐색하게 되는 키보드 초점 오류를 방지할 수 있습니다. 하지만 문제는 여전히 존재합니다. 레이어를 닫을 때 초점이 머물던 요소가 사라지면서 IE 6~10 브라우저는 키보드 초점을 페이지 맨 처음으로 돌려놓습니다. 이것 때문에 키보드 트랩에 빠지게 되는 것입니다. 레이어 이후의 항목을 탐색할 수 없게 되는 문제가 발생합니다.

레이어가 닫히는 순간 키보드 트랩에서 빠져나오기

이 문제를 해결하려면 레이어가 닫힐 때 논리적으로 납득할만한 위치로 초점을 옮겨야만 했습니다. 대부분의 최신 브라우저들(크롬, 파이어폭스, 사파리, 오페라)은 키보드 초점이 머물던 요소가 사라지는 경우 레이어 이후의 맥락을 탐색할 수 있도록 키보드 초점이 자연스럽게 처리가 됩니다. 하지만 IE 6~10 브라우저는 그렇지 못했기 때문에 문제가 됩니다. 또한 레이어의 위치가 문맥에 맞지 않게 엉뚱한 곳에서 펼쳐지는 경우에는 표준 브라우저도 여전히 엉뚱한 위치로부터 탐색을 시작하기 때문에 문제가 됩니다.

자바스크립트 내공이 없어서 이 문제를 끙끙 앓다가 트위터와 페이스북에 도움을 요청했는데요. 몇몇 지인 분들께서 제가 작성한 코드를 보완해 주셨습니다. 레이어를 닫을 때 레이어를 열었던 앵커로 초점을 옮겨주는 방식입니다.

정답이 없는 문제이기 때문에 어떤 코드가 좋고 나쁘다고 단적으로 말하기는 어렵습니다. 다만 제가 고민하던 문제를 어떤 방법으로든 해결했다는 것이 더 중요한 것 같네요. 문제를 함께 해결해 주신 여러분께 진심으로 감사드립니다.

만약 여러분이라면 이 문제를 어떻게 해결하시겠어요? 직접 코드로 보여주시면 더 좋구요.

참고 2013-05-29 업데이트

키보드 접근성을 보장한 모달 다이얼로그 데모도 참고로 보세요. http://webhipster.com/testing/accessibility/modal-dialog-latest/

분류: 웹 기획,웹 접근성,자바스크립트 | 2013년 4월 24일, 9:27 | 정찬명 | 댓글: 16개 |
트랙백URI - http://naradesign.net/wp/2013/04/24/1996/trackback/

16개의 댓글이 있습니다.

  1. wassup82 댓글:

    항상 이곳에서 많은걸 배우고 갑니다. 먼저 감사의 말씀을 드리고 싶어요~
    궁금한 점과 제안을 드리고 싶은 것이 있어 찬명님 및 다른 분들께 여쭐께요.

    1. 본문에 링크를 주신 분들께서 이미 훌륭한 해답을 주셨는데요~ 레이어가 앵커 바로 다음에 위치하지 않기 때문에 반드시 레이어를 닫아야 앵커로 이동을 하는군요. 레이어를 닫지 않고 띄워놓은 상태에서 다음 앵커로 이동을 해야 하는 경우가 있을 수도…

    2. 위와 같이 레이어를 띄워 놓은 상태에서 다음 내용를 사용하다가 다시 이전 내용으로 포커스를 이동시킨다고 가정하겠습니다. 이전에 레이어를 띄운 앵커에 도달하였을 경우 띄워 놓은 레이어에 다시 접근을 시키는게 좋을까요?? (키보드 접근성에서 웹접근성에 관한 이슈로 발전시키는 생각입니다. 앵커 바로 다음에 레이어를 위치시키면 간단히 해결되겠지만 레이어를 다른 위치에 놓을 경우가 참 어렵네요…)

    3. 레이어의 키보드 접근성 트랩문제를 해결하면, 앵커 바로 다음에 레이어를 위치시키지 않아도 웹접근성을 준수한 것으로 봐도 될까요? (컨텐츠의 선형화에 위배가 되는게 아닐런지요?)

  2. 정찬명 댓글:

    @wassup82
    1번 상황을 구체적으로 설명해 주실 수 있나요? 레이어를 열어 놓고 탐색하지 않은 상태에서 다른 링크를 탐색해야만 하는 경우가 어떤 상황인지요?

    2. 사용자가 의도적으로 클릭하거나 엔터를 입력하지 않은 경우에는 초점을 제작자 의도에 따라 함부로 옮기면 안됩니다. 키보드 접근성 문제는 원래 웹 접근성 문제의 한 분야입니다.

    3. 만약 숨김이 기본값인 레이어 콘텐츠라면 페이지 하단에 분리되어 있어도 좋다고 생각합니다. 왜냐하면 원래부터 없어도 맥락 파악하는데 문제가 없는 콘텐츠라면 페이지 하단에 분리되어 있어도 문제가 없다는 의미입니다. a href 값을 유효하게 작성하고 앵커 클릭시 초점만 제대로 옮겨준다면 말이죠.

  3. 임국태 댓글:

    안녕하세요. UI프레임워크를 만들고 있는 웹퍼블리셔 임국태라고 합니다.

    블로그에 기재하신 글 중에 레이어팝업 관련한 글을 보고 질문 드립니다.^^

    저희 UI프레임워크 중에도 레이어팝업이 있는데 접근성을 준수하다보니 별다른 대안이 없어 현재 띄우는 버튼 다음에 마크업이 위치하게 되어있습니다.

    실무 프로젝트에 적용해보니, 많은 반발(?)이 있었습니다ㅠㅠ 이유로는..

    부모의 overflow:hidden이 있는경우 레이어팝업이 안보이거나, ie6,7에서 z-index버그를 만나 전체 레이아웃의 z-index설계를 다시 해야된다거나 등..

    기존 UI프레임워크를 사용하시던 분들이 접근성을 준수한걸 쓰니 오히려 제약사항이 많다는 의견이 많았습니다. ㅠ

    그러던 한줄기 빛(?)같은 찬명님의 글을 봤습니다. 테스트 해보니 ie6에서도 잘 되더군요..

    근데 http://naradesign.net/wp/2012/05/10/1786/ 이 글을 읽어보니 tabindex가 a, area, button, input, object, select, textarea 요소에 지원된다고 하던데..

    이렇게 div에 걸어도 괜찮은 건지 궁금합니다.. 유효성을 체크해보니 걸리진 않더군요..

    그리고 레이어팝업을 닫을 시 포커스가 띄우는 버튼이나 링크 다음으로 가는게 아니라 다시 그 버튼이나 링크로 가도 접근성에는 괜찮은지 궁금합니다..

    글을 논리정연하게 못써서 죄송합니다.ㅠㅠ

  4. 정찬명 댓글:

    @임국태
    HTML4 명세에 보면 “tabindex 속성 지원 여부에 관계 없이 “0″의 값이 할당된 요소는 그 다음으로 탐색된다. 이 요소들은 코드 안에서 등장하는 순서대로 탐색된다.” 라는 문장이 있습니다. div와 같은 요소라도 초점을 받을 필요가 있는 경우 사용할 수 있습니다. 하지만 오용(예를 들면 div에 tabindex 속성을 넣고 onclick 이벤트를 추가하는 등)하지 않는 것이 중요하다고 생각합니다.

    레이어를 닫을 때 초점을 어느 곳으로 보내야 하는지는 원래 정답이 없는 문제인데요. 제 생각에는 레이어를 여는 링크로 다시 보내는 것이 가장 좋다고 생각합니다. 다른 곳으로 보내는 경우 사용자의 의도에 맞지 않을 수 있기 때문입니다. 예를 들면 사용자가 레이어 링크 이후를 탐색하겠다는 의도가 항상 참인것은 아니기 때문에 초점을 원래 자리(레이어를 여는 링크)로 돌려보내는 것이 좋다고 생각한 것입니다. 만약 제작자가 의도적으로 레이어를 여는 링크 이후로 초점을 보낸다면 사용자는 전후 맥락을 파악하기 위해 Shift+Tab을 누를 확률이 높다고 생각합니다.

  5. EveR™ 댓글:

    마침 모달 팝업 접근성 때문에 고민이 이만저만 아니였는데…
    좋은 정보 제공해주셔서 감사합니다. ^^

  6. KingWangZZang 댓글:

    다른 얘기일 수도 있고, 아닐 수도 있지만
    모달창에 뒷쪽 (뒷쪽 부모 페이지 링크 인풋, 브라우저 주소창, 툴바 등)에 포커스가 가지 않도록
    하는것도 필요할 듯 합니다.
    확인결과 jquery ui 다이얼로그에선 그렇게 처리되었더군요.

  7. 김군우 댓글:

    WAI-ARIA의 Authoring Practices 중 “모달 다이얼로그 만들기” 부분을 일부 발번역해보았어요. 다이얼로그 내에 키보드 초점을 가둔다던가 다이얼로그가 열리고 닫힐 때 구체적으로 초점을 어디에 위치시켜야 하는지 등에 대해 자세히 다루고 있어 참고할만한 내용이 많은 듯 해요. :D

    http://mctenshi.tumblr.com/post/49257115608/wai-aria-authoring-practices

  8. 반슬 댓글:

    안녕하세요.
    장차법 대응 프로젝트 관련해서, 비슷한 사례로 고민하다가 setTime을 걸어서 레이어가 열리고 후에 포커스를 가게 하는 방법을 잠깐 해보다가 이것도 아이폰(보이스 오버)에서 원활하게 이동하지 못하더군요,

    마침 좋은 예를 주셔서 테스트 해보았으나, 똑같더군요, 웹에서는 foucs명령이 잘 적용되나, 아이폰 보이스오버에서는 가질 않는군요,(보이스오버 자체 문제인지)
    포커스가 현재 화면 기준으로 맨 상단으로 가버리거나 조금 이상하게 가게 됩니다.
    혹시 이에 관한 사례가 있으신지요.

  9. 정찬명 댓글:

    @김군우 @KingWangZZang
    포스트의 아쉬운 부분을 매워 주셔서 감사합니다. (ㅡㅡ)

  10. 정찬명 댓글:

    @반슬
    터치 기반의 장치에서는 어떻게 동작해야 하는지까지 고민해 보지는 못했는데요. 보이스오버는 초점을 받을 수 없는 요소에 강제로 초점을 옮겨도 적절하게 대응을 못 해주네요. 개인적인 생각을 말씀드리면 현재로써는 터치기반 장치를 위해 별도의 추가 대응을 한다는 것이 조심스러운 입장입다.

  11. 에이미 댓글:

    이런 대단한 곳을 오늘 알았다는 것에 큰 멘붕과 희망이..겹치네요 ㅋㅋ
    많이 배우러 오겠습니다~!!

  12. 권태성 댓글:

    접근성 관련 작업을 하고 있는데 정리리가 잘되어 이해가 쉬웠습니다.

    정말 감사합니다.

  13. 정찬명 댓글:

    @권태성
    여기 http://oaa-accessibility.org/examples/ 링크에 더 좋은 예제가 많습니다. ^^

  14. 권태성 댓글:

    와 정말 감사합니다. ^^

  15. 리베하얀 댓글:

    늘 부족함을 느끼네요 ^^..
    많은 도움되었습니다.

댓글 쓰기

전송된 글이 나타나지 않는다면 필터링 된 것입니다. dece24앳gmail.com 으로 메일 주세요.
(X)HTML 코드 사용이 가능하지만 소스 코드 출력을 원하시면 <꺽쇠>는 [괄호]로 변환하여 작성해 주세요.

필수 아님

필수 아님