웹 접근성을 고려한 input checkbox 마크업

김채은·2024년 5월 18일
1
post-thumbnail

배경

Text Me! 소셜 로그인 약관 페이지를 개발하며 체크박스를 사용했다. HTML에서 제공하는 input 요소를 그대로 사용해도 되지만, UI의 통일성을 위해 SVG 아이콘을 사용했다.

<label>
  // display: none
  <input
    type="checkbox"
    checked={totalAgree}
    onChange={totalAgreeChange}
  />
  // 동의 유무에 따른 아이콘 변경
  { totalAgree ? 
   <CheckFilled size={22} />
    : <CheckOutlined size={22} />
  }
  <span>전체 동의하기</span>
</label>

display: none을 사용하여 input 태그를 숨기면 다음과 같이 나타냈다.

문제점과 해결

디지털 정부서비스 UI/UX 가이드라인을 참고하여 해당 페이지의 접근성 이슈를 파악했다.

1. 체크박스 키보드 탐색 및 실행 불가

키보드만을 이용해서 웹을 탐색하는 사용자는 tab 키를 사용하여 input을 포커스 한 뒤 space 키를 사용하여 체크박스를 선택한다. display: none을 입힌 요소는 스크린 리더가 인지할 수 없어, 키보드 tab 키를 이용해서 탐색할 수 없다. 이외에도 visibility: hidden이나 opacity: 0과 같은 CSS 속성을 input 요소에 사용해서는 안된다.

체크박스를 키보드로 탐색하고 실행할 수 있도록 한다.
사용자 에이전트에서 제공되는 기본 체크박스가 아니라 커스텀 디자인을 사용하는 경우에 기본 체크박스에 display:none, visibility:hidden, opacity:0과 같은 스타일을 하면 스크린 리더에서 체크박스의 역할을 인지할 수 없으며 키보드로 옵션을 선택할 수 없게 된다.

  • KWCAG 2.2 키보드 사용 보장
  • WCAG 2.1 Keyboard (A)
  • WCAG 2.1 No Keyboard Trap (A)

해결

위에 해당되는 속성들 대신 appearance: none을 사용해서 input 요소가 가지고 있는 기본 스타일을 제거했다.
이렇게 하면 input 요소를 숨기면서도 키보드를 통해 접근하고 선택할 수 있다.

2. 체크박스 키보드 초점 미표시

하지만 위의 방식 역시 문제가 있다. input 디자인을 숨기게 되면 현재 어디에 포커스가 돼있는지 알 수 없기 때문에, 스페이스 키를 언제 눌러야 할지 알기 어렵다.

체크박스에 초점이 명확하게 표시되도록 한다.
사용자 에이전트에서 제공되는 기본 체크박스가 아니라 커스텀 디자인을 사용하는 경우 키보드 초점이 시각적으로 표시되도록 스타일을 제공해야 한다. 체크박스 요소를 시각적으로 숨기는 경우, 시각적으로 표시되고 있는 체크박스 양식과 숨겨진 요소의 크기와 위치를 일치시켜 포커스링이 적절하게 표시되도록 구현해야 한다.

  • KWCAG 2.2 초점 이동
  • WCAG 2.1 Focus Visible (AA)
  • WCAG 2.1 Non-text Contrast (AA)
  • tab 키 탐색
  • space 키 선택

위 예시처럼 현재 focus된 input은 적절한 포커스링이 표시되어야 한다.

해결

input 요소에 적절한 padding을 넣어서 focus 시 outline이 체크박스 주변으로 노출되게 했다.

  input {
    appearance: none;
    position: absolute;
    margin: 0px;
    padding-inline: 12px;
    padding-block: 13px;
  }
 
 input:focus{
    outline: solid 2px #0f59d9;
    border-radius: 1%;
  }

하지만 위와 같은 방법은 마우스를 클릭했을 때도 outline이 노출되기 때문에 마우스 사용자에게 불필요한 UI를 노출하게 된다. 이럴 땐 focus-visible을 사용해보자. 그러면 마우스를 통한 focus가 발생했을 때는 해당 속성이 적용되지 않고, 키보드를 통한 focus가 발생했을 때만 적용되게 된다.

  input:focus-visible {
    outline: solid 2px #0f59d9;
    border-radius: 1%;
  }

나는 UI 통일을 위해 global style로 focus 속성을 지정해주어서, :not() 가상 클래스를 통해 키보드 focus가 아닐 때 CSS 속성을 따로 추가해주었다.

// global
input{
    outline: solid 2px #0f59d9;
    border-radius: 1%;
}

// checkbox
input{
    appearance: none;
    position: absolute;
    margin: 0px;
    padding-inline: 12px;
    padding-block: 13px;
}

input:focus:not(:focus-visible){
	outline: 0;
}

3. checkbox 순차적 탐색 불가

다음의 화면에서 사용자는 일반적으로

전체 동의하기 > [필수] > [선택 1] > [선택 2]

와 같은 순서로 요소를 탐색하기를 기대한다.

하지만 실제로 [필수] 체크박스 뒤에 자세히 요소가 배치돼있기 때문에, 사용자는

전체 동의하기 > [필수] > 자세히 1 > 자세히 2 > [선택 1] > [선택 2]

순서로 요소를 탐색하게 된다.

해결

tab-index 속성을 통해 tab 키가 요소를 포커스하는 순서를 지정해줄 수 있다. 대화형 컨텐츠는 기본값으로 tab-index=0을 가지고 있다. 우선순위는 값이 0보다 큰 경우 값이 클 수록 먼저 포커스 되며, 0은 맨 마지막에, -1은 포커스되지 않는다.

<input
   type="checkbox"
   tabIndex={1}
/>

체크박스에 1을 설정해주자 전체 동의하기 > [필수] > [선택 1] > [선택 2] > 자세히 1 > 자세히 2 순으로 탐색하게 되었다.

4. 스크린리더의 불필요한 컨텐츠 탐색

input 요소를 화면에서 숨겼지만 스크린리더는 여전히 input을 읽는다. input을 숨겼기 때문에 추가된 체크박스 아이콘인 svg 요소 역시 스크린리더를 통해 읽히는데, 내용이 담기지 않은 디자인 요소이기 때문에 사용자의 탐색에 방해요인이 될 수 있다.

해결

aria-hidden가 적용된 요소는 스크린리더의 탐색에서 제외된다. 따라서 사용자는 input과 label 등 유의미한 요소를 탐색하는 데 집중할 수 있다.

<label>
	{requiredAgree ? (
  		<CheckFilled size={18} aria-hidden />
  		) : (
  		<CheckOutlined size={18} aria-hidden />
	)}
</label>

마무리

이외에도 체크박스 디자인 가이드 등 접근성을 위해 고려해야 할 사항이 있으나, 우선 마크업 요소에 집중하여 웹 접근성 점검을 해보았다.

웹 접근성은 「지능정보화기본법」에 따라 장애인이나 고령자분들이 웹 사이트에서 제공하는 정보를 비장애인과 동등하게 접근하고 이용 할 수 있도록 보장하는 것으로, 법적의무사항이다. 선택이 아닌 필수사항이기 때문에 서비스를 개발하는 사람이라면 반드시 숙지하고 있어야 하는 부분이며, 서비스 제공 전 필히 점검해야 한다.

서비스 완성과 런칭, 기능 개발이 급한 상황에서 접근성 요소까지 고려하는 게 쉽지는 않지만, 시간을 내서라도 점검해야 하는 부분이라는 생각이 들어 체크하는 시간을 가졌다. 구글링하는 과정에서도 많은 정보를 얻을 수 없어서 정리를 해보았는데 많은 이들에게 도움이 되었으면 좋겠다.

profile
배워서 남주는 개발자 김채은입니다 ( •̀ .̫ •́ )✧

0개의 댓글