모달 대화상자 예제
다음은 모달 대화상자에 대한 설계 패턴의
구현 예제입니다.
다음 배송지 추가
버튼은 다른 대화상자를 여는 두 개의 버튼을 포함하는 모달 대화상자를 엽니다.
접근성 기능 섹션은 초기 초점 배치와 각 대화상자에서 aria-describedby
의 사용의 근거를 설명합니다.
유사한 예는 다음과 같습니다:
- 알림(alert) 대화상자 예제: 알림 대화상자를 보여주는 확인 프롬프트.
- 날짜 선택기 대화상자 예제: 날짜를 선택하기 위한 달력 그리드를 포함하는 대화상자를 보여줍니다.
예제
배송지 추가
확인 결과
이것은 시연일 뿐입니다. 실제 어플리케이션이었다면, 입력된 주소가 유효한지 여부를 알려주는 메세지가 제공될 것입니다.
시연 목적을 위해, 이 대화상자는 많은 텍스트를 가집니다. 다음과 같은 시나리오를 보여줍니다:
- 첫 번째 대화형 엘리먼트, 도움말 링크는 대화상자의 바닥에 있습니다.
- 대화상자가 열릴 때 첫 번째 인터랙티브 엘리먼트에 초점이 배치되는 경우, 유효성 검사 메세지가 보이지 않을 수 있습니다.
- 유효성 검사 메세지가 표시되고 도움말 링크에 초점이 있는 경우, 초점이 보이지 않을 수 있습니다.
-
대화상자가 열릴 때, 다음 두 가지가 중요합니다:
- 사용자가 읽기 위해 뒤로 스크롤 할 필요가 없도록 텍스트의 시작 부분이 보입니다.
- 키보드 초점은 항상 시각적으로 표현됩니다.
이 문제를 해결하는 몇 가지 방법이 있습니다:
- 인터랙티브 엘리먼트, 예를 들어 버튼이나 링크를 대화상자의 최상단에 배치합니다.
- 정적 엘리먼트, 예를 들어, 대화상자 제목이나 텍스트의 첫 번째 블록을 초점을 얻을 수 있게(focusable) 만드세요.
dialog 역할(role)을 가진 엘리먼트를 초점을 얻을 수 있게(focusable) 만들지 마세요!
- 초점을 얻을 수 있는(focusable) 엘리먼트가 클 수록, 특히 좁은 시야를 가진 사용자에게, 초점의 위치를 시각적으로 식별하는 것은 더 어렵습니다.
- 대화상자가 시각적 테두리를 가지므로, 전체 대화상자가 초점을 가질 때 명확한 초점의 시각적 표시기를 만드는 것은 매우 실현 가능하지 않습니다.
- 스크린리더는 초점을 얻을 수 있는(focusable) 엘리먼트의 레이블과 컨텐츠를 읽습니다. 대화상자는 자체 레이블과 많은 컨텐츠를 포함합니다! 이와 같은 대화상자가 초점을 가지고 있는 경우, 실제 초점을 이해하기 어렵습니다.
이 대화상자에서, 첫 번째 문단은 tabindex=
를 가지고 있습니다.
첫 번째 문단은 대화상자 설명을 제공하는 엘리먼트 내부에도 포함됩니다, 즉, 엘리먼트는 -1
aria-describedby
에 의해 참조 됩니다.
일부 스크린리더의 경우, 이는 대화상자가 열릴 때 부정적이지만
상대적으로 사소한 부작용 --
첫 번째 문단이 두 번 낭독될 수 있습니다.
그럼에도 불구하고, 첫 번째 문단이 초점을 얻을 수 있게(focusable) 만들고 초기에 초점을 설정하는 것이 가장 광범위한 접근 가능한 선택사항 입니다.
마지막!
어디로도 이동하지 않는 가짜 링크나 버튼을 활성화했습니다! 링크나 버튼은 데모용으로만 제공됩니다.
접근성 특성
- 작은 화면에 표시된 콘텐츠를 더 쉽게 읽을 수 있도록, 대화상자는 화면의 100%를 채웁니다. 배경 창을 완전히 덮는 것은 대화상자 내부의 콘텐츠를 스크롤할 때 일부 모바일 기기에서 발생하는 배경 움직임도 숨겨집니다.
- 초점과 접근 가능한 설명은 각 대화상자의 콘텐를 기반으로 설정됩니다.
배송지 추가
대화상자 (id=dialog1):- 초기 초점이 첫 번째 초점을 얻을 수 있는(focusable) 엘리먼트인 첫 번째 input에 설정됩니다.
- 대화상자는 이를 설명하는 정적 텍스트가 없기 때문에
aria-describedby
가 필요하지 않습니다. 취소
행위의 결과로 대화상자가 닫힐 경우, 초점을배송지 추가
버튼으로 되돌려 사용자의 관점이 유지됩니다.-
추가
행위의 결과로 대화상자가 닫히고주소 추가
대화상자가배송지 추가
대화상자를 교체하는 경우,배송지 추가
대화상자는배송지 추가
버튼에 대한 참조를주소 추가
대화상자에 전달하여 닫힐 때 사용자의 관점을 유지할 수 있습니다.
확인 결과
대화상자 (id=dialog2):- 첫 번째 인터랙티브 엘리먼트가 바닥에 있고 이는 텍스트의 길이로 인해 보이지 않기 때문에 초기 초점이 첫 번째 문장에 설정됩니다.
- 스크린리더 사용자가 대화상자 텍스트를 인식하는 것을 지원하기 위해, 대화상자 텍스트는
aria-describedby
로 참조되는div
으로 래핑됩니다. - 대화상자가 닫힐 때, 사용자의 관점을 유지하기 위해, 초점이
주소 확인
버튼으로 돌아갑니다. - 이 대화상자의 텍스트는 많은 양의 텍스트를 가진 대화상자의 초기 초점과 접근 가능한 설명에 대한 설계 고려 사항을 기술합니다.
주소 추가
대화상자 (id=dialog3):-
초기 초점은 마지막 초점을 얻을 수 있는(focusable) 엘리먼트인
확인
버튼에 설정됩니다. 이는 대부분의 사용자가 메세지를 읽는 즉시 대화상자를 간단하게 닫을 것이기 때문에 효율성을 위한 것입니다. 사용자는프로필
링크에 초점을 주기 위해 Tab을 누를 수 있습니다. - 대화상자 메세지를 포함하는 엘리먼트는 대화상자가 열릴 때 스크린리더 사용자에게 알려져야 함을 암시하기 위해
aria-describedby
에 의해 참조됩니다. - 대화상자가 닫힐 때,
배송지 추가
버튼에 초점을 설정하여 사용자의 관점이 유지됩니다.
-
초기 초점은 마지막 초점을 얻을 수 있는(focusable) 엘리먼트인
마지막!
대화상자 (id=dialog4):- 이 대화상자는 대화상자가 열릴 때 초점을 얻는 단 하나의 초점을 얻을 수 있는(focusable) 엘리먼트만 가집니다.
- dialog3와 마찬가지로,
aria-describedby
는 스크린리더 사용자를 위한 메세지 알림을 용이하게 하는 데 사용됩니다. 주소 추가
확인 대화상자를 제외하고 이 예제의 모든 다른 대화상자와 마찬가지로, 대화상자가 닫힐 때, 대화상자 표시를 트리거한 엘리먼트에 초점을 반환하여 사용자의 관점이 유지됩니다.
키보드 지원
키 | 기능 |
---|---|
Tab |
|
Shift + Tab |
|
Escape | 대화상자를 닫으세요. |
Role, Property, State, Tabindex 어트리뷰트
역할(role) | 어트리뷰트 | 엘리먼트 | 사용법 |
---|---|---|---|
dialog |
div |
대화상자 컨테이터로 제공되는 엘리먼트를 식별시킵니다. | |
aria-labelledby= |
div |
대화상자 제목을 제공하는 엘리먼트를 참조하여 대화상자에 접근 가능한 이름을 제공합니다. | |
aria-describedby= |
div |
|
|
aria-modal= |
div |
현재 대화상자 아래 창이 상호작용 할 수 없음(비활성)을 보조 기술에 알립니다. |
aria-modal
과 aria-hidden
에 대한 참고 사항
-
aria-modal
속성(property)은 ARIA 1.1에서 도입되었습니다. 새로운 속성으로서, 스크린리더 사용자는 다양한 수준의 지원을 경험할 수 있습니다. -
aria-modal
속성(property)을dialog
엘리먼트에 적용하는 것은 대화상자 외부 콘텐츠가 비활성임을 보조 기술에 알리기 위해 배경에aria-hidden
을 사용하는 기술을 대체합니다. -
보조 기술 사용자를 위해 대화상자 외부 콘텐츠를 비활성으로 만드는데
aria-hidden
가 사용되는 레거시 대화상자 구현에서는, 다음이 중요합니다:- 비활성 레이어의 일부를 포함하는 각 엘리먼트에
aria-hidden
이true
로 설정됩니다. - 대화상자 엘리먼트는
true
로 설정 된aria-hidden
을 가진 엘리먼트의 하위 항목이 아닙니다.
- 비활성 레이어의 일부를 포함하는 각 엘리먼트에
Javascript와 CSS 소스 코드
- CSS: dialog.css
- Javascript: dialog.js, utils.js
HTML Source Code