🎄 A11y Advent Calendar (번역) 9일차입니다. 전체 목록을 보고싶으시면 여기로 이동해주세요 :)
웹은 본질적으로 Form입니다. 사용자가 링크 클릭 이상의 상호작용을 원하는 순간, Form을 통해 이루어집니다. 검색창, 채팅창, 설문지 등 모두 Form의 일종입니다.
Form은 모든 사용자가 효율적으로 사용할 수 있도록 세심하게 설계되어야 합니다. 키보드로 탐색하는 파워 유저부터 스크린 리더를 사용하는 시각장애인까지, 다양한 사용자들에게도 지루하지 않고 편리하게 작성될 수 있도록 주의가 필요합니다.
다음은 접근성 높은 Form을 만들기 위한 핵심 사항들입니다
Label
모든 필드에는 반드시 label을 지정해야 합니다. label은 디자인에 따라 시각적으로 숨길 수 있지만, DOM에 반드시 포함되어야 하며, for와 id 속성을 사용해 해당 필드와 정확히 연결되어야 합니다. 참고로 placeholder는 label의 역할을 대신할 수 없습니다.
또한, label에는 입력 형식(필요한 경우)과 해당 필드가 필수인지 여부를 명확히 표시해야 합니다. 만약 모든 필드가 필수라면, Form 상단에 이를 알리는 안내 메시지를 추가하는 것이 좋습니다.
<label for="ssn">Social Security Number (xxx-xxx-xxx) (required)</label>
<input type="text" name="ssn" id="ssn" required />
Errors
Form에서 흔히 발생하는 문제 중 하나는 잘못된 오류 처리입니다. 오류는 전체 Form이 아닌, 개별 필드 단위로 보고되어야 합니다. 그러나 사용 중인 API에 따라 이를 구현하기 어려운 경우도 있어, 프론트엔드 개발자가 API 설계 단계에 적극적으로 참여하는 것이 중요합니다
필드는 aria-described-by/ id 속성 쌍을 통해 해당 error 컨테이너에 매핑되어야 합니다. 접근성 트리에서 매핑을 수행할 수 있도록 오류 컨테이너가 error 발생 여부와 관계없이(JS로 동적으로 삽입되지 않고) DOM에 항상 존재하는 것이 매우 중요합니다.
<label for="age">Age</label>
<input type="number" name="age" id="age" aria-describedby="age-errors" />
<div id="age-errors"></div>
error를 표시한 후에는 초점을 관련 필드로 이동해야 합니다. 오류가 여러 개 표시된 경우에는 첫 번째 유효하지 않은 필드로 초점을 이동해야 합니다. 이러한 오류 처리는 HTML 기본 유효성 검사를 통해 기본적으로 처리될 수 있으므로 가능하면 이를 적극 활용하세요.
비활성화된 버튼
비활성화된 버튼은 접근성 트리에서 제거되므로 스크린 리더로 검색되지 않습니다. 이는 Form의 유일한 버튼이 보조 기술로 감지되지 못하는 문제를 초래할 수 있습니다. 이 문제를 해결하려면 제출 버튼을 완전히 비활성화하지 않고, 버튼을 클릭했을 때 Form의 유효성 검사를 수행하도록 설계해야 합니다.
버튼이 여전히 보조 기술에서 검색 가능하도록 aria-disabled="true" 속성을 설정해 기술적으로 활성화되지 않았음을 나타낼 수 있습니다. 이를 통해 버튼이 시각적으로 비활성화된 것처럼 보이지만, 접근성 트리에서는 인식될 수 있도록 합니다. 추가로, CSS를 활용해 aria-disabled="true" 속성을 가진 버튼을 비활성화된 상태로 스타일링하면 사용자에게도 명확하게 전달됩니다.
드물지만 비활성화된 버튼이 허용되는 경우도 있습니다:
- set의 첫 번째/마지막 항목에 도달할 때 이전/다음 버튼. 예를 들어 슬라이더의 navigation 버튼이 있습니다.
- 특정 시간에 초점을 맞출 수 없어야 하는 화면 밖 컨트롤. 예를 들어, 슬라이더에서 비활성 슬라이드 내의 버튼입니다.
기타
이름이 같은 라디오 input은 자체 <legend>가 있는 <fieldset> 요소 내에서 그룹화해야 합니다. 이는 화살표 키를 사용하여 순환할 수 있도록 하기 위해 중요합니다.
<fieldset>
<legend>How comfortable are you with #a11y?</legend>
<label for="very"> <input type="radio" name="a11y" id="very" /> Very </label>
<label for="so-so">
<input type="radio" name="a11y" id="so-so" /> So-so
</label>
<label for="not-at-all">
<input type="radio" name="a11y" id="not-at-all" /> Not at all
</label>
</fieldset>
출처: Day 9) Forms
'웹 접근성' 카테고리의 다른 글
Day 11) 접근성을 고려한 이모티콘 (1) | 2024.12.16 |
---|---|
Day 10) ARIA란 (0) | 2024.12.16 |
Day 8) 이미지의 대체 텍스트(alt text) (0) | 2024.12.03 |
Day 7) SPA와 접근성: 페이지 제목과 포커스 관리하기 (1) | 2024.12.02 |
Day 6) Skip to Content를 추가하여 접근성 높이기 (0) | 2024.11.28 |