[WAI-ARIA 리마인드] 커스텀 radio 구현 시 흔히 하는 실수
우리는 일반적으로 라디오 버튼을 어떻게 사용할까요? 일반적으로는 이렇게 사용합니다.
<fieldset>
<legend>성별</legend>
<label for="male">
<input type="radio" id="male" name="gender" checked>
남성
</label>
<label for="female">
<input type="radio" id="female" name="gender">
여성
</label>
</fieldset>
보통은 이런식으로 사용할 거에요. 그렇죠?
“어...? 저는 이렇게 안 쓰는데요?”
...그렇다고 칩시다. 아무튼, 일반적으로 HTML에서 지원하는 기본 input의 radio 유형은 기본적으로 name 속성을 매개로 그루핑합니다. 일반적으로
스크린리더에서는 해당 요소에 접근하게 되면, 그룹 내 총 라디오 버튼의 개수와 현재 라디오버튼이 몇 번째 항목인지 알려주게 됩니다.
그런데, WAI-ARIA로 만든다면 어떨까요? 보통은 이런 모습을 상상하실 가능성이 높습니다. 실제 서비스에서도 많이 보입니다.
<div id="lb_male">
남자
</div>
<div aria-labelledby="lb_male" tabindex="0" aria-checked="true" role="radio" class="c-radio">
</div>
<div id="lb_female">
여자
</div>
<div aria-labelledby="lb_female" tabindex="-1" aria-checked="false" role="radio" class="c-radio">
</div>
라디오 버튼만을 각 개별적으로 놓고보면, 문제가 없는 코드일 수 있습니다. 하지만, 이 코드는 틀린 코드입니다. WAI-ARIA 명세에 맞지 않는 코드에요.
아까 위에서 그루핑에 관해 언급했습니다. WAI-ARIA 명세에 따르면 role="radio" 항목은 role="radiogroup" 안에 있어야 합니다.
WAI-ARIA 명세에는 아래와 같이 써 있습니다.
* * *
radio
role
A checkable input in a group of elements with the same role, only one of which can be checked at a time.
Authors SHOULD ensure that elements with role radio
are explicitly grouped in order to indicate which ones affect the same value. This is achieved by enclosing the radio elements in an element with role radiogroup
. If it is not possible to make the radio buttons DOM children of the radiogroup
, authors SHOULD use the aria-owns
attribute on the radiogroup
element to indicate the relationship to its children.
[번역] radio 역할
동일한 역할(radio)을 가진 요소들 중, 한 번에 오직 하나만 체크(선택)될 수 있는 체크 가능한 입력입니다.
작성자는 radio 역할을 가진 요소들을 명시적으로 그룹화해야 합니다. 이렇게 해야 어떤 버튼들이 같은 값을 제어하는지(서로 배타적으로 동작하는지)를 보장할 수 있습니다.
일반적으로는 이들 radio 요소를 role="radiogroup" 을 가진 요소 안에 포함시켜 그룹화합니다.
만약 radio 버튼들을 DOM 자식으로 radiogroup 안에 둘 수 없다면, aria-owns 속성을 radiogroup 요소에 지정하여 해당 radio 요소들과의 관계를 표시해야 합니다.
* * *
당연하게도, 위 코드에서는 그룹을 이루는 아무런 매개체가 없습니다. 그렇기 때문에, 스크린리더 입장에서는 각 라디오 항목을 별개의 그룹처럼 인식하게 될 가능성이 높고, 올바른 순서와 목록 항목 수를 읽지 못할 겁니다.
<div role="radiogroup" aria-label="성별">
<div id="lb_male">
남자
</div>
<div aria-labelledby="lb_male" tabindex="0" aria-checked="true" role="radio" class="c-radio">
</div>
<div id="lb_female">
여자
</div>
<div aria-labelledby="lb_female" tabindex="-1" aria-checked="false" role="radio" class="c-radio">
</div>
</div>
이전 코드도, 충분히 접근성을 향상시키고자 하는 서비스팀과 개발자의 노력이 보이는 코드였습니다. 그런데, 잘 만들어놓고, 단 하나의 태그 계층 차이로 틀린 코드가 되어버렸네요. WAI-ARIA 유형으로 무언가를 만들 때는 항상 이런 부분을 신경써서 사용하는 습관을 들이는 것이 중요하겠습니다. 특히 여러 개 중 하나를 선택하는 요소는 무조건 이런 계층 유형이 들어간다는 점! 기억해두시면 좋습니다.
글을 끝내며, 항상 리마인드 차원에서 말하는 부분이지만, WAI-ARIA는 Required가 아니라 어쩔 수 없을 때 쓰는 Optional한 기술입니다. 가급적, 이미 있는 태그는 WAI-ARIA 대신 여러 기법을 사용해서 다듬는 것이 좋습니다.