아티클

[모바일 접근성] 팝업 버튼 접근성 알아보기

2024-02-15 09:42:50

안녕하세요. 널리 접근성팀 서미연입니다.

모바일 접근성을 진단하면서 요즘 눈에 띄게 팝업 버튼을 커스텀 컨트롤로 제공한 사례를 많이 만나게 되는데요.
올바르게 제공하는 경우보다는 잘못 적용해서 오히려 사용성을 해치는 경우가 늘어나고 있습니다.
그래서 이번 글에서는 커스텀 팝업 버튼에 접근성을 향상시키는 방법에 대해 알아보겠습니다.

 

*테스트정보 : iOS 16.6 iPhone 12 Pro Max / Android 14 Galaxy S23 Ultra

 

1. HTML

기본 컨트롤이 아닌 커스텀 컨트롤을 제공해야 할 때는 기본 컨트롤이 제공하고 있는 유형 정보, 상태 정보를 동등하게 제공하는 것이 중요한데요.


유형 정보와 상태 정보의 중요성은 아래 글에서 확인하실 수 있습니다.
[모바일 접근성] #대체 텍스트와 #보조기술과의 호환성 알아보기


 

1-1. select 네이티브

기본 네이티브 팝업 버튼이 모바일 스크린리더에서 어떤 정보를 제공하는지 먼저 확인해 보겠습니다. 입력 서식의 제목인 label 요소와 select 요소를 id + for로 연결하여 제공합니다. 

<label for="btn_lang">언어 선택</label>
<select id="btn_lang">
    <option selected>한국어</option>
    <option>중국어</option>
    <option>일본어</option>
</select>

스크린리더에서 어떻게 들리는지 음성 정보를 확인해 볼게요.

  • iOS - VoiceOver 음성 정보 :

언어 선택, 한국어, 팝업버튼, 픽커를 활성화하려면 이중 탭하십시오.
선택됨, 한국어, 버튼
중국어, 버튼
일본어, 버튼

  • Android - TalkBack 음성 정보 :

접힘, 한국어, 메뉴 팝업 버튼, 언어 선택, 활성화하려면 두 번 탭하세요.
선택됨, 한국어, 목록에 있음. 두 번 탭하여 선택하세요.
중국어, 두 번 탭하여 선택하세요.
일본어, 두 번 탭하여 선택하세요.

 

 

모바일의 경우 입력 서식의 용도를 알려주는 제목을 감추고 컨트롤만 보이는 경우가 많은데요. 이 경우 label을 select 뒤로 감추거나 title 속성을 통해 입력 서식의 용도를 제공 할 수 있습니다.

<select title="정렬 방식">
    <option selected>이미지 뷰</option>
    <option>리스트 뷰</option>
</select>

스크린리더에서 어떻게 들리는지 음성 정보를 확인해 볼게요.

  • iOS - VoiceOver 음성 정보 :

정렬 방식, 이미지 뷰, 팝업버튼, 픽커를 활성화하려면 이중 탭하십시오.

  • Android - TalkBack 음성 정보 :

접힘, 이미지 뷰, 메뉴 팝업 버튼, 정렬 방식, 활성화하려면 두 번 탭하세요.

 

 

1-2. select 커스텀 

자 그럼 이제 select 컨트롤을 접근성이 잘 적용된 커스텀 컨트롤로 적용해 보겠습니다.
다음과 같이 button과 ul 기본 태그를 통해 팝업 버튼과 옵션 목록을 제공했다고 가정해 볼게요.

<button>한국어</button>
<ul>
    <li><a href="#" class="on">한국어</a></li>
    <li><a href="#">중국어</a></li>
    <li><a href="#">일본어</a></li>
</ul>

스크린리더로 얻을 수 있는 정보는 다음과 같습니다.

  • iOS - VoiceOver 음성 정보 :

한국어, 버튼
한국어, 링크
중국어, 링크
일본어, 링크

  • Android - TalkBack 음성 정보 :

한국어, 버튼, 활성화하려면 두 번 탭하세요.
목록 상자
한국어, 링크, 활성화하려면 두 번 탭하세요.
중국어, 링크, 활성화하려면 두 번 탭하세요.
일본어, 링크, 활성화하려면 두 번 탭하세요.

 

위 정보를 통해 스크린리더 사용자는 "버튼" 또는 "링크" 유형 정보 이외 얻을 수 있는 정보가 없습니다. 이 음성 정보를 통해 이 버튼의 기능이 팝업 버튼이라는 것을 알기란 어렵습니다. 또한 옵션 목록에서 선택된 옵션인 한국어에서 "선택됨" 상태 정보를 읽어주지 않기 때문에 사용자가 옵션 목록 중 어떤 것이 선택된 값인지 빠르게 인지할 수 없습니다.

 

접근성을 향상시켜볼께요~

1) 버튼 

먼저 팝업 버튼에 해당하는 button에 WAI-ARIA 역할 중 role="combobox"를 제공하여 "콤보 상자" 또는 "드롭 다운 목록" 유형 정보를 제공하여 사용자가 보다 컨트롤을 이해할 수 있도록 합니다. 콤보 상자 또는 드롭 다운 목록은 입력 서식이기 때문에 입력 서식의 용도를 정확히 이해할 수 있도록 제목 또는 도움말 등을 제공해야 하는데요. aria-label 을 통해 입력 서식의 용도를 제공할 수 있습니다. (role="combobox"를 제공하지 않고 aria-label을 제공한다면 버튼의 대체 텍스트로 사용되기 때문에 반드시 입력 서식으로서의 제목을 제공하고자 하신다면 입력 서식 역할을 선언해 주셔야 돼요. )
combobox 역할이 있는 요소는 암시적으로 aria-haspopup="listbox"가 적용된다고 합니다. 다만 호환성을 위해 aria-haspopup="listbox"를 선언하고, 옵션 목록이 펼쳐진 상태인지 접힌 상태인지 알려주기 위해 aria-expanded 속성을 선언해 줍니다.

<button role="combobox" aria-label="언어 선택" aria-haspopup="listbox" aria-expanded="true">한국어</button>

스크린리더에서 어떻게 들리는지 음성 정보를 확인해 볼게요.

  • iOS - VoiceOver 음성 정보 :

언어 선택, 한국어, 콤보 상자, 목록 상자 팝업, 확장됨, 축소하려면 이중 탭하십시오.(축소됨, 확장하려면 이중 탭하십시오.)

  • Android - TalkBack 음성 정보 :

펼쳐짐(접힘), 한국어, 드롭다운 목록, 언어 선택, 변경하려면 두 번 탭하세요.

 


참고해 주세요~! combobox 키보드 접근성
https://w3c.github.io/aria/#combobox
WAI-ARIA 1.3 콤보 상자 스펙을 보면 편집 및 입력을 지원하는 요소에 제공하도록 권고하고 있습니다. 키보드 입력을 받을 수 있는 형태여야 하는데요. 옵션 값과 동일한 키보드키를 입력했을 때 옵션 값이 자동으로 선택된다거나, 키보드키를 이용하여 콤보 상자를 사용 할 수 있도록 해야 함을 의미합니다.
네이티브 팝업 버튼과 동일한 키보드 접근성을 제공해야 완벽한 커스텀 콤보 상자로서 사용자가 불편함 없이 사용 할 수 있습니다.
키보드 접근성 및 다양한 패턴의 커스텀 콤보 상자 예제는 다음 URL 에서 확인 하실 수 있습니다.
[WAI-ARIA 권장 사용 패턴] combobox https://www.w3.org/WAI/ARIA/apg/patterns/combobox/
[널리 WAI-ARIA UI] 선택목록 https://nuli.navercorp.com/tool/waiAria


 

꼭 role="combobox" 역할을 제공해야 할까요? 

단순 팝업 버튼으로 제공할 경우 role="combobox"는 제공하지 않아도 됩니다 . aria-haspopup과 aria-expanded 속성을 통해 이 버튼의 기능이 팝업 버튼임을 제공 할 수 있습니다. 다만 팝업 버튼으로 제공할때는 aria-label을 제공하게 되면 대체 텍스트로서 기본 텍스트 정보를 덮어쓰기 때문에 title을 제공하여 도움말을 통하여 버튼의 용도를 제공할 수 있습니다.

<button title="언어 선택" aria-haspopup="listbox" aria-expanded="true">한국어</button>

스크린리더에서 어떻게 들리는지 음성 정보를 확인해 볼게요.

  • iOS - VoiceOver 음성 정보 :

한국어, 팝업 버튼, 목록 상자 팝업, 언어 선택, 픽커를 활성화하려면 이중 탭하십시오.

  • Android - TalkBack 음성 정보 :

펼쳐짐(접힘), 한국어, 팝업 버튼, 언어 선택, 활성화하려면 두 번 탭하세요.

 

 


참고해 주세요~! aria-haspopup 알아보기

aria-haspopup는 위에 예시처럼 하위에 팝업 요소를 갖는 경우 정보 접근성을 위해 제공하는 속성입니다. 초기 wai-aria 1.0에서는 하위 항목을 갖는 요소에 true/false를 적용해서 해당 요소가 하위 항목의 유무 정도의 정보를 제공했다면 현재 wai-aria 1.3에서는 더욱 세분화된 값을 제공하도록 권고하고 있습니다. 단순 하위 항목을 갖고 있다의 의미로 aria-haspopup="true"를 제공하게 되면 현재 스크린리더에서는 메뉴 항목을 갖은 팝업 버튼으로 알려주어 오히려 사용자에게 혼란을 주는 경우가 발생하였습니다. 하위에 어떤 팝업 요소냐에 따라 값을 정의해 주어야 합니다. aria-haspopup을 제공할 때는 aria-expanded를 제공해서 버튼을 눌렀을 때 팝업이 펼쳐졌는지 접혀졌는지 상태 정보 꼭 함께 제공하는 것이 바람직합니다. (aria-haspopup과 aria-expanded는 짝꿍이래요~) aria-haspopup 값에 대해 더 알아보겠습니다.

① menu

메뉴 팝업을 가지고 있음을 나타냅니다. 메뉴 항목을 갖는 버튼에 적용합니다.

VoiceOver 음성 정보 TalkBack 음성 정보
팝업 버튼, 메뉴 팝업 메뉴 팝업 버튼

aria-haspopup menu 예시_첨부 메뉴 팝업버튼

② listbox

목록 상자 팝업을 가지고 있음을 나타냅니다. combobox 또는 select 컨트롤과 같은 리스트 항목을 갖는 버튼에 적용합니다.

VoiceOver 음성 정보 TalkBack 음성 정보
팝업 버튼, 목록 상자 팝업 팝업 버튼

aria-haspopup listbox 예시_보기정렬 팝업버튼

aria-haspopup listbox 예시_언어선택 팝업버튼

aria-haspopup listbox 예시_제휴 팝업버튼

③ dialog 

대화상자 팝업을 가지고 있음을 나타냅니다. 팝업을 갖는 버튼에 적용합니다.

VoiceOver 음성 정보 TalkBack 음성 정보
팝업 버튼, 대화 팝업 대화상자 팝업 버튼

aria-haspopup dialog 예시 - 대화상자 팝업버튼

aria-haspopup dialog 예시 - 알림대화상자 팝업버튼

④ tree 

트리 팝업을 가지고 있음을 나타냅니다. 트리 항목을 갖는 버튼에 적용합니다.

VoiceOver 음성 정보 TalkBack 음성 정보
팝업 버튼, 나무 팝업 팝업 버튼

⑤ grid 

그리드 팝업을 가지고 있음을 나타냅니다. 그리드 항목을 갖는 버튼에 적용합니다.

VoiceOver 음성 정보 TalkBack 음성 정보
팝업 버튼, 격자 팝업 팝업 버튼

⑥ true 와 false(기본값) 

  • true 

menu 값과 동일합니다.

VoiceOver 음성 정보 TalkBack 음성 정보
팝업 버튼, 메뉴 팝업 메뉴 팝업 버튼
  • false 

팝업이 없음을 의미합니다.


 

2) 목록

이어서 다음은 옵션 목록에 해당하는 ul 요소에 role="listbox"를 제공해서 리스트 목록임을 알 수 있도록 제공하고 옵션에 해당하는 요소에 role="option" 과 aria-selected 상태 정보를 제공하여 선택됨 상태까지 제공합니다.

<ul role="listbox">
    <li role="none"><a href="#" role="option" aria-selected="true">한국어</a></li>
    <li role="none"><a href="#" role="option" aria-selected="false">중국어</a></li>
    <li role="none"><a href="#" role="option" aria-selected="false">일본어</a></li>
</ul>

스크린리더에서 어떻게 들리는지 음성 정보를 확인해 볼게요.

  • iOS - VoiceOver 음성 정보 :

선택됨, 한국어, 목록 시작
중국어
일본어, 목록 끝

  • Android - TalkBack 음성 정보 :

항목 3개, 목록 상자
선택됨, 목록의 항목 3개 중 1번째, 한국어, 활성화하려면 두 번 탭하세요.
목록의 항목 3개 중 2번째, 중국어, 활성화하려면 두 번 탭하세요.
목록의 항목 3개 중 3번째, 일본어, 활성화하려면 두 번 탭하세요.

접근성을 향상시키기 전에는 "버튼" 또는 "링크" 유형 정보 이외 얻을 수 있는 정보가 없습니다. 옵션 목록에서도 선택됨 상태 정보를 읽어주지 않아 사용성에 어려움이 있었는데요. 접근성 정보를 추가한 후에는 "콤보 상자" 또는 "드롭 다운 목록" 또는 "팝업 버튼" 유형 정보로 제공하고 있고 그에 맞는 힌트 메시지를 스크린리더에서 제공하여 사용자가 명확하게 해당 컨트롤의 기능을 이해할 수 있게 되었습니다. 옵션 목록에서는 "목록 시작/ 목록 끝" 또는 "목록의 항목 n 개 중 n 번째" 목록 위치 정보와 "선택됨" 상태 정보를 제공하여 사용자가 바르게 이해하고 옵션을 선택할 수 있게 되었습니다.


참고해 주세요~! iOS 옵션 목록 유형 정보

  • iOS의 경우 옵션 목록에서 개별 옵션 항목에 대해서 "버튼"으로 유형 정보를 제공할 수 없으나 "팝업 버튼" 유형 정보를 제공했으므로 다음 옵션 목록이 나타날 것을 알 수 있으며, UL 태그에 role="listbox"를 제공하여 "목록 시작", "목록 끝" 항목 정보를 제공하고 있으므로 사용자가 선택 가능 요소임을 충분히 이해할 수 있습니다. 네이티브 옵션 목록과 동일하게 "버튼" 유형 정보로 제공할 수 없는 것이 선택됨 상태 정보를 제공하기 위해서는 wai-aria 역할 중 gridcell, option, row, tab으로 제한되어 있습니다. button 역할에 선택됨 정보를 제공하는 aria-selected 상태를 제공할 경우 W3C Markup Validation에서 오류로 체크가 됩니다. button 역할이 가질 수 있는 상태는 aria-disabled, aria-haspopup, aria-expanded, aria-pressed입니다.
    https://w3c.github.io/aria/#button
    https://w3c.github.io/aria/#aria-selected

 

1-3. 팝업 버튼 초점 순서 

네이티브 select 컨트롤의 경우 팝업 버튼을 누르면 옵션 목록 첫 번째 요소로 초점이 이동이 됩니다. 옵션을 선택 한 후에는 다시 팝업 버튼으로 초점이 이동시켜 줍니다. select 커스텀 컨트롤을 제공하셔야 한다면 초점을 동일하게 구현해 주시는 것이 바람직합니다.
초점을 보내는 방법은 .focus() 함수를 통해 초점을 이동시켜 줍니다.

 

2. iOS

xcode 13 이상부터 오브젝트 라이브러리에 pull down button 과 popup button이 추가가 되어 스토리보드에 올려두고 접근성 정보가 어떻게 들리는지 확인해 보았습니다. (추가된 지 오래됐는데 이제서야 포스트하게 됐어요~ ㅜ, ㅜ)


pull down button HIG 문서 확인하기
popup button HIG 문서 확인하기


Objects 라이브러리에 pull down button 과 popup button 버튼 추가

팝업 버튼으로 읽어줄거라 예상했지만 "버튼"으로 읽혀지고, 선택된 옵션의경우 "선택됨" 상태 정보와 "버튼" 유형 정보로 읽혀지고 있습니다.

스크린리더에서 어떻게 들리는지 음성 정보를 확인해 볼게요.

pull down button  음성 정보 :

더보기, 버튼
설정, 버튼
공지사항, 버튼
버전, 버튼

popup button 음성 정보 :

이름순, 버튼
선택됨, 이름순, 버튼
날짜순, 버튼
추천순, 버튼

버튼으로 읽혀지는 당연한 이유는 pull down button 과 popup button 구성을 확인해보면 UIButton 클래스와 UIMenu 클래스 이기 때문입니다.
pull down button과 popup button 구조

 

popup button 접근성 향상시키기

popup button의 경우 버튼의 대체 텍스트가 선택된 옵션 값으로 읽히기 때문에 사용자가 이 버튼이 팝업 버튼인지는 버튼을 선택한 후 옵션 목록으로 가기 전까지는 알기 어려운데요. 사용성을 고려한다면 버튼의 용도를 사용자가 이해할 수 있도록 accessibliltyLabel을 제공하여 버튼의 용도를 제공하는 것을 권장하고 있습니다. 또한 선택한 옵션 값은 accessibilityValue에 담아 제공해야 버튼의 용도와 현재 선택된 옵션 값을 사용자가 제공받을 수 있습니다. 이 정보를 통해 해당 버튼이 팝업 버튼임을 알 수 있습니다.

accessibliltyLabel을 제공하고 accessibilityValue를 제공하지 않는다면 옵션값을 선택하더라도 accessibliltyLabel만 스크린리더가 읽어주기 때문에 꼬옥~ accessibilityValue도 함께 제공해 주셔야 합니다.

 button.accessibilityLabel = "보기 정렬"       //대체 텍스트
 button.accessibilityValue = action.title    // 선택한 값

스크린리더에서 어떻게 들리는지 음성 정보를 확인해 볼게요.

보기 정렬, 이름순, 버튼

 

여기까지 긴 글을 읽어주셔서 감사합니다.


내가 개발한 앱! 어떤 정보들이 읽히는지 알고 싶다면 바로 스크린리더를 켜고 들어보세요. 그리고 접근성 개선을 시작해주세요.
[모바일 스크린리더 기본 사용법 #Android TalkBack]
[모바일 스크린리더 기본 사용법 #iOS VoiceOver]


댓글 0
댓글을 작성하려면 해주세요.