A11y Patterns
모든 패턴

Select (Listbox)

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

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

기본 코드 예시

Baseline (React)tsx
Loading...

공통 베이스라인

모든 디자인 시스템에 적용
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 탐색 중에 자동으로 값이 변경되면 스크린리더 사용자가 원치 않는 선택이 발생합니다.

디자인 시스템별 구현

추가 체크포인트

  • FormControl + InputLabel 조합 필수

    MUI Select는 FormControl과 InputLabel을 함께 사용해야 올바른 레이블이 연결됩니다.

코드 샘플

MUI Selecttsx
Loading...

구현 노트

  • labelId와 InputLabel의 id가 일치해야 스크린리더가 레이블을 읽습니다.
  • native prop을 사용하면 브라우저 기본 <select>로 렌더링됩니다.
  • disabled 옵션에는 aria-disabled가 자동으로 적용됩니다.

참고 문서