A11y Patterns
모든 패턴
패턴

Select (Listbox)

목록에서 하나의 옵션을 선택하는 커스텀 드롭다운 컴포넌트

관련 WCAG 기준 — 클릭하여 상세 보기

01 — 코드

기본 코드 예시

Baseline (React)tsx
Loading...
02 — 규칙

공통 베이스라인

모든 디자인 시스템에 적용
Must5
  • role="listbox"와 role="option" 사용

    커스텀 select는 컨테이너에 role="listbox", 각 항목에 role="option"을 명시해야 합니다.

  • 레이블 연결

    트리거 버튼에 aria-labelledby 또는 aria-label로 레이블을 연결해야 합니다.

  • 키보드 내비게이션

    ArrowUp/ArrowDown으로 옵션 이동, Enter/Space로 선택, Escape로 닫기를 지원해야 합니다.

  • 선택 상태 표시

    선택된 옵션에 aria-selected="true"를 설정하고, 트리거에 aria-expanded로 열림/닫힘 상태를 표시해야 합니다.

  • 포커스 관리

    팝업 열릴 때 선택된 옵션(없으면 첫 번째)으로 포커스 이동, 닫힐 때 트리거로 포커스 복귀해야 합니다.

Should3
  • 타입어헤드 지원

    키보드로 문자를 입력하면 해당 문자로 시작하는 옵션으로 포커스가 이동하도록 구현하세요.

  • Home/End 키 지원

    5개 이상의 옵션이 있을 때 Home/End 키로 첫 번째/마지막 옵션으로 이동을 지원하세요.

  • 그룹화에 role="group" 사용

    옵션이 그룹으로 나뉘는 경우 role="group"과 aria-label로 그룹을 구분하세요.

Avoid2
  • div/span으로만 구현

    시맨틱 없이 div/span만으로 드롭다운을 구현하면 스크린리더가 인식하지 못합니다. role 속성이 필수입니다.

  • 탐색 중 자동 선택

    ArrowKey 탐색 중에 자동으로 값이 변경되면 스크린리더 사용자가 원치 않는 선택이 발생합니다.

03 — 구현

디자인 시스템별 구현

추가 체크포인트

  • FormControl + InputLabel + labelId 연결 필수

    MUI Select는 FormControl, InputLabel(id), Select(labelId)를 일치시켜야 스크린리더가 레이블을 올바르게 읽습니다. outlined variant에서는 Select의 label prop도 동일하게 설정하세요.

  • error + helperText로 오류 안내

    FormControl의 error prop과 FormHelperText를 함께 사용하면 오류 상태와 메시지가 aria-describedby로 자동 연결됩니다.

코드 샘플

MUI Selecttsx
Loading...

구현 노트

  • InputLabel의 id와 Select의 labelId를 반드시 동일하게 설정하세요. 미설정 시 스크린리더가 레이블을 읽지 못합니다.
  • outlined variant에서는 Select의 label prop도 InputLabel 텍스트와 동일하게 설정해야 floating label 애니메이션이 올바르게 동작합니다.
  • disabled MenuItem은 aria-disabled가 자동 적용됩니다.
  • native={true} prop으로 브라우저 기본 <select> 렌더링으로 전환할 수 있어 모바일 접근성이 향상됩니다.
04 — 참고

참고 문서