A11y Patterns
모든 패턴
패턴

Navigation Menu

드롭다운 하위 메뉴를 포함하는 사이트 내비게이션 컴포넌트

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

01 — 코드

기본 코드 예시

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

공통 베이스라인

모든 디자인 시스템에 적용
Must4
  • <nav> 랜드마크와 aria-label

    사이트 내비게이션은 <nav> 요소로 감싸고 aria-label로 레이블을 제공해야 합니다.

  • 하위 메뉴 트리거에 aria-expanded

    하위 메뉴를 여는 버튼에 aria-expanded로 열림/닫힘 상태를 표시해야 합니다.

  • 키보드 완전 지원

    Tab으로 항목 이동, Enter/Space로 하위 메뉴 열기, Escape로 닫기, Arrow 키로 하위 항목 탐색을 지원해야 합니다.

  • aria-current="page" 설정

    현재 활성 페이지에 해당하는 링크에 aria-current="page"를 설정해야 합니다.

Should3
  • aria-haspopup="menu" 추가

    하위 메뉴가 있는 트리거에 aria-haspopup="menu"를 추가하면 스크린리더가 서브메뉴 존재를 미리 알 수 있습니다.

  • Escape로 닫기

    열린 하위 메뉴를 Escape 키로 닫고 트리거로 포커스가 복귀해야 합니다.

  • 포커스 트랩 없이 자연스러운 흐름

    내비게이션 메뉴는 포커스 트랩 없이 Tab으로 메뉴 밖 이동 시 하위 메뉴가 닫혀야 합니다.

Avoid2
  • hover로만 하위 메뉴 열기

    hover 이벤트만으로 하위 메뉴를 열면 키보드 사용자가 접근할 수 없습니다.

  • 여러 <nav>에 동일한 레이블

    여러 <nav> 요소에 동일한 aria-label을 사용하면 스크린리더 사용자가 구분할 수 없습니다.

03 — 구현

디자인 시스템별 구현

추가 체크포인트

  • Toolbar에 component="nav"와 aria-label 설정

    AppBar의 Toolbar를 component="nav"로 사용하고 aria-label="Main navigation"을 제공하세요. 이렇게 하면 <nav aria-label>로 렌더링되어 스크린리더 랜드마크 탐색이 가능합니다.

  • Menu 트리거에 aria-haspopup과 aria-expanded

    하위 메뉴 트리거 버튼에 aria-haspopup="menu"와 aria-expanded를 설정해야 스크린리더가 서브메뉴의 존재와 상태를 파악할 수 있습니다.

  • 현재 페이지 링크에 aria-current="page"

    MUI는 aria-current를 자동으로 설정하지 않습니다. 현재 경로에 해당하는 링크에 직접 aria-current="page"를 추가하세요.

코드 샘플

MUI AppBar Navigationtsx
Loading...

구현 노트

  • Toolbar component="nav"로 <nav> 시맨틱을 부여하고 aria-label로 목적을 명시하세요.
  • MUI Menu는 방향키 탐색, Escape 닫기, 포커스 복원을 자동으로 처리합니다.
  • 현재 페이지 링크에 aria-current="page"를 직접 추가해야 합니다. MUI는 자동 처리하지 않습니다.
  • MenuListProps={{ "aria-label": "..." }}로 메뉴 목록에 레이블을 추가할 수 있습니다.
04 — 참고

참고 문서