드롭다운 및 메뉴 시스템
목적
드롭다운 및 메뉴 시스템 스킬은 웹 인터페이스 전반에 걸쳐 부동 액션 메뉴, 오버플로 메뉴, 컨텍스트 메뉴, 계층형 서브메뉴를 설계하기 위한 표준화된 프레임워크를 제공합니다. 드롭다운 메뉴는 트리거 요소(예: 아이콘 버튼, 분할 버튼, 컨텍스트 액션)에 연결된 대화형 명령, 옵션, 하위 액션의 구성된 목록을 표시합니다.
효과적인 드롭다운 메뉴 시스템을 설계하려면 공간 레이아웃, 시각적 위계, 항목 그룹화, 키보드 내비게이션 의미론, 충돌 처리(뷰포트 경계), 터치 기반 모바일 뷰포트에서의 반응형 적응을 사용자 방해 없이 WCAG 2.1 AA 접근성 지침을 준수하도록 균형을 맞춰야 합니다.
사용 사례
- 액션 및 옵션 메뉴: 데이터 테이블, 카드, 페이지 헤더에서 트리거 버튼에 연결된 보조 페이지 또는 행 액션(예: "편집", "복제", "내보내기", "삭제")을 표시합니다.
- 오버플로 및 더보기 메뉴: 컨테이너 공간이 제한될 때(예: 도구 모음 또는 테이블 헤더의 "..." 버튼) 우선순위가 낮은 도구나 탐색 링크를 수용합니다.
- 컨텍스트 팝업 메뉴: 특정 시각적 캔버스 또는 목록 항목에서 우클릭 또는 길게 누르기를 통해 트리거되는 대상 컨텍스트 명령을 표시합니다.
- 계층형 서브메뉴: 다단계 메뉴 오버레이 내에 중첩된 액션이나 다중 레벨 카테고리 옵션을 구성합니다.
- 선택 액션 메뉴(체크 가능 및 라디오 항목): 부동 액션 패널 내에서 보기 상태, 열 가시성, 정렬 환경 설정을 전환합니다.
사용하지 말아야 할 경우
- 양식 선택 입력(콤보박스 및 선택 입력): 사용자가 필드를 채우기 위해 하나 이상의 값을 선택하는 양식 입력(예: 국가 또는 제품 카테고리 선택)의 경우
custom-select-and-combobox-system을 사용하세요. - 고밀도 탐색 패널: 구조화된 카테고리, 랜딩 페이지, 마케팅 프로모션을 포함하는 다중 열 전역 사이트 탐색의 경우
mega-menu-navigation-system을 사용하세요. - 대형 모달 및 작업 워크스페이스: 복잡한 하위 작업, 다중 필드 편집, 또는 포커스 유지가 필요한 다단계 마법사 양식의 경우
overlay-and-dialog-system또는bottom-sheet-design-system을 사용하세요. - 컨텍스트 도움말 및 툴팁: 요소의 기능을 설명하는 비대화형 호버/포커스 텍스트 설명의 경우
tooltip-and-hint-system을 사용하세요.
입력
- 트리거 컴포넌트 및 지오메트리: 기본 트리거 요소 유형(표준 버튼, 아이콘 버튼, 분할 버튼, 또는 우클릭 대상 영역) 및 공간 배치.
- 메뉴 항목 인벤토리 및 계층 구조: 액션 목록, 항목 유형(표준, 체크 가능, 라디오, 파괴적), 아이콘, 키보드 단축키, 구분선, 섹션 그룹 레이블.
- 표면 및 고도 토큰:
elevation-and-depth-system및accessible-color-system의 배경 표면 색상, 테두리 스타일, 드롭 섀도우 토큰(--elevation-popover), z-인덱스 배치(--z-popover). - 뷰포트 및 기기 컨텍스트: 기기 방향, 화면 너비 중단점, 터치 지원 특성.
출력
- 메뉴 구성 및 레이아웃 청사진: 메뉴 컨테이너 크기, 패딩, 항목 정렬, 후행 단축키 힌트, 섹션 구분선 간격에 대한 CSS 및 HTML 구조 사양.
- 공간 배치 및 충돌 전략: 앵커 위치(상단/하단/왼쪽/오른쪽), 정렬, 동적 뒤집기/슬라이드 로직, 최대 높이 스크롤 가능 경계에 대한 레이아웃 규칙.
- 반응형 모바일 적응 모델: 좁은 데스크톱 드롭다운 팝오버를 모바일 뷰포트에서 바텀 액션 시트(
bottom-sheet-design-system) 또는 전체 너비 터치 목록으로 변환하는 설계 사양. - ARIA 및 키보드 내비게이션 사양: ARIA 역할(
role="menu",role="menuitem",role="menuitemcheckbox",role="menuitemradio"), 확장 상태(aria-expanded), 화살표 키 포커스 관리를 포함하는 프로그래밍 방식 접근성 규칙.
워크플로우
1. 메뉴 구조 및 항목 구성 정의
메뉴 내 항목을 논리적 기능 그룹으로 분류하여 스캔 가능성을 극대화합니다.
- 헤더 및 섹션 레이블: 대문자 마이크로 타이포그래피 또는 미묘한 섹션 헤더(
font-size: 0.75rem,font-weight: 600,letter-spacing: 0.05em)를 사용하여 관련 액션을 그룹화합니다. - 표준 항목 구성: flexbox(
gap: 0.75rem)를 사용하여 요소를 수평으로 정렬합니다.- 선행 그래픽: 액션 목적을 명확히 하는 16x16px 또는 20x20px 아이콘.
- 레이블 텍스트: 간결하고 액션 지향적인 동사(예: "PDF 다운로드", "항목 복제").
- 후행 단축키 힌트: 모노스페이스 키보드 단축키 텍스트(예:
⌘E,Ctrl+D)를 시각적으로 흐리게 표시(color: var(--text-tertiary)). - 후행 쉐브론: 계층형 서브메뉴 트리거를 나타냅니다(
>).
- 특수 항목 유형:
- 체크 가능 항목 (
role="menuitemcheckbox"): 활성화 시 선행 체크 표시를 표시합니다. - 라디오 항목 (
role="menuitemradio"): 그룹 내에서 선택 시 라디오 점을 표시합니다. - 파괴적 항목: 부정적 액션(예: "삭제", "제거")을 별개의 경고 색상 토큰(
color: var(--color-danger))으로 스타일링하고, 시각적 구분선으로 무해한 액션과 분리합니다.
- 체크 가능 항목 (
- 구분선 (
role="separator"): 미묘한 수평선(1px solid var(--border-subtle))을 사용하여 별개의 액션 그룹을 구분합니다(예: 보기 액션을 편집/삭제 액션과 그룹화).
2. 공간 배치 및 충돌 처리 설정
메뉴가 트리거에 깔끔하게 인접하여 화면 가장자리를 넘치지 않도록 레이아웃 규칙을 구성합니다.
- 앵커 정렬: 트리거 버튼 경계를 기준으로 메뉴 팝오버를 배치합니다.
- 하단-왼쪽 / 하단-오른쪽: 트리거 버튼 아래 기본 배치. 트리거가 오른쪽 화면 경계 근처에 있을 때 오른쪽 가장자리에 정렬합니다(예: 데이터 테이블 행 액션 열).
- 상단-왼쪽 / 상단-오른쪽: 뷰포트 하단 근처일 때 트리거 버튼 위로 방향을 뒤집습니다.
- 뷰포트 충돌 및 뒤집기 규칙:
- 화면 가장자리에서 최소 12px 여백을 유지합니다(
viewport-margin: 12px). - 긴 메뉴의 경우 최대 높이 제약 조건(
max-height: calc(100vh - 32px))을 설정하고 내부 세로 스크롤(overflow-y: auto)을 적용합니다.
- 화면 가장자리에서 최소 12px 여백을 유지합니다(
- 고도 토큰: 최상위 레이어 스태킹(
z-index: var(--z-popover))과 드롭 섀도우(box-shadow: var(--shadow-popover))를 적용하여 부동 메뉴를 배경 테이블 행이나 카드와 시각적으로 분리합니다.
3. 상호작용 및 서브메뉴 동역학 구성
- 트리거 상태:
aria-expanded="true"와 미묘한 눌린 시각적 상태(background-color: var(--bg-hover))를 사용하여 트리거 버튼이 열린 상태를 나타내도록 합니다. - 서브메뉴 호버 및 키보드 지연:
- 계층형 서브메뉴는 마우스 호버 시 약간의 의도적 지연(150–200ms 의도 타이머) 후에 열려 포인터 이동 중 우발적인 트리거 깜빡임을 방지합니다.
- 서브메뉴 트리거에서
ArrowRight를 누르면 서브메뉴가 확장되고 포커스가 내부로 이동합니다.ArrowLeft는 서브메뉴를 닫고 포커스를 부모 메뉴 항목으로 되돌립니다.
- 해제 트리거: 다음 경우에 열린 메뉴 오버레이를 해제합니다.
- 사용자가 메뉴 패널 외부를 클릭합니다(클릭-외부 리스너).
- 사용자가
Escape키를 누릅니다. - 활성 메뉴 항목 액션이 실행됩니다(체크 가능 토글 항목 제외).
- 포커스가 메뉴 오버레이를 벗어납니다.
4. 반응형 모바일 적응 설계
데스크톱 부동 드롭다운 팝오버(예: 220px 부동 상자)는 작은 터치 대상과 정밀한 배치 요구 사항으로 인해 모바일 터치 화면에서 성능이 좋지 않습니다.
- 모바일 터치 변환 (
< 768px):- 데스크톱 팝오버를 하단 뷰포트에 고정된 바텀 액션 시트(
bottom-sheet-design-system)로 변환합니다. - 항목 행 높이를 최소 터치 대상 44px(가급적 48px)로 늘리고 전체 너비 수평 터치 영역을 제공합니다.
- 시트 하단에 명시적인 시각적 드래그 핸들이나 명확한 "취소" 버튼을 제공하여 엄지손가락으로 쉽게 해제할 수 있도록 합니다.
- 데스크톱 팝오버를 하단 뷰포트에 고정된 바텀 액션 시트(
- 터치 피드백: 즉각적인 촉각 피드백을 위해
:active상태의 뚜렷한 활성 터치 배경 상태를 적용합니다.
5. 접근성 및 키보드 의미론 프로그래밍
- ARIA 랜드마크 및 역할 매핑:
- 트리거 버튼 설정:
aria-haspopup="menu",aria-expanded="true|false",aria-controls="menu-id". - 메뉴 컨테이너 설정:
role="menu",aria-labelledby="trigger-id",tabindex="-1". - 메뉴 항목 설정:
role="menuitem",role="menuitemcheckbox", 또는role="menuitemradio".
- 트리거 버튼 설정:
- 키보드 내비게이션 모델:
- 트리거에서
Enter/Space/ArrowDown: 메뉴를 열고 첫 번째 메뉴 항목에 포커스를 둡니다. ArrowDown/ArrowUp: 메뉴 항목을 순차적으로 포커스 이동합니다(위에서 아래로 순환).Home/End: 첫 번째 또는 마지막 메뉴 항목으로 직접 포커스를 이동합니다.Escape: 메뉴를 즉시 닫고 포커스를 트리거 버튼으로 되돌립니다.Tab: 메뉴를 즉시 닫고 표준 문서 포커스 진행을 허용합니다.- 타입어헤드 문자 검색: 문자 키(예: "D")를 누르면 해당 문자로 시작하는 다음 메뉴 항목으로 포커스가 직접 이동합니다.
- 트리거에서
결정 규칙
메뉴 유형 및 컨텍스트 선택
| 컨텍스트 / 목표 | 권장 패턴 | ARIA 구조 | 모바일 적응 |
|---|---|---|---|
| 행 / 카드 액션 | 액션 드롭다운 | role="menu" / role="menuitem" | 바텀 액션 시트 |
| 도구 모음 오버플로 ("...") | 오버플로 메뉴 | role="menu" / role="menuitem" | 바텀 액션 시트 |
| 우클릭 캔버스 도구 | 컨텍스트 메뉴 | role="menu" / role="menuitem" | 길게 누르기 바텀 시트 |
| 양식 옵션 선택 | 콤보박스 선택 | role="combobox" / role="option" | 네이티브 선택 / 바텀 시트 |
| 다중 계층 보기 / 필터 토글 | 체크 가능 액션 패널 | role="menu" / role="menuitemcheckbox" | 바텀 액션 시트 |
배치 및 정렬 규칙
- 데이터 테이블 행 메뉴: 오른쪽 테이블 뷰포트 가장자리를 넘어 수평으로 잘리는 것을 방지하기 위해 트리거 버튼에 오른쪽 상단 또는 오른쪽 하단 정렬.
- 헤더 / 탐색 액션: 화면 가장자리와의 근접성에 따라 오른쪽 하단 또는 왼쪽 하단 정렬.
- 서브메뉴: 기본적으로 오른쪽으로 열림(
left: 100%). 오른쪽 공간이 200px 미만이면 왼쪽으로 열리도록 뒤집힙니다(right: 100%).
제약 조건
- 접근성 (WCAG 2.1 AA):
- SC 1.4.3 대비 (최소): 항목 텍스트, 아이콘, 키보드 힌트는 메뉴 배경에 대해 최소 4.5:1 대비 비율을 유지해야 합니다.
- SC 2.1.1 키보드: 메뉴 내 모든 항목과 액션은 키보드로 완전히 접근 가능하고 트리거 가능해야 합니다.
- SC 2.4.7 포커스 가시성: 포커스된 메뉴 항목은 뚜렷한 시각적 포커스 상태(예: 배경색 전환 + 대비를 준수하는 하이라이트 표시기)를 가져야 합니다.
- SC 2.5.8 대상 크기: 데스크톱 메뉴 항목은 최소 32px 높이를 유지해야 합니다. 모바일 액션 시트 항목은 최소 44x44px 터치 대상을 충족해야 합니다.
- 뷰포트 경계 제약 조건: 열린 메뉴는 화면 밖으로 확장되거나 수평 페이지 스크롤바를 생성해서는 안 됩니다. 충돌 뒤집기 및 내부 세로 스크롤(
max-height)을 사용합니다. - 공간 패딩 및 밀도: 일관된 내부 수평 패딩(예:
padding: 0.5rem 0.75rem) 및 수직 컨테이너 패딩(padding: 0.25rem 0)을 유지합니다.
일반적인 실패 패턴
- 양식 콤보박스 혼동: 양식 선택 드롭다운에
role="combobox"/role="listbox"대신role="menu"를 사용하여 스크린 리더가 값 선택과 명령 실행을 혼동하게 함. - 닫기 시 포커스 방향 상실:
Escape또는 선택을 통해 메뉴가 닫힐 때 키보드 포커스를 트리거 버튼으로 복원하지 못해 포커스가document.body에서 사라짐. - 클리핑 컨테이너 함정: 드롭다운 메뉴를
overflow: hidden이 있는 테이블 셀이나 컨테이너 내에 배치하여 열린 메뉴가 시각적으로 잘림. - 작은 모바일 터치 대상: 작은 24px 데스크톱 드롭다운 항목을 터치 친화적인 바텀 시트로 변환하지 않고 터치 화면에 그대로 렌더링.
- 우발적 서브메뉴 해제: 계층형 서브메뉴에 의도 타이머 지연이 없어 마우스가 하위 항목을 향해 대각선으로 이동할 때 서브메뉴가 접힘.
검증 기준
- 메뉴 컨테이너가 적절한 ARIA 의미론을 사용합니다(
role="menu",role="menuitem",role="separator"). - 키보드 내비게이션이
ArrowDown,ArrowUp,Home,End,Escape및 문자 타입어헤드를 완전히 지원합니다. - 메뉴 닫기(
Escape또는 항목 클릭)가 프로그래밍 방식으로 트리거 요소에 포커스를 복원합니다. - 뷰포트 충돌 규칙이 긴 메뉴를 화면 넘침 없이 깔끔하게 뒤집거나 스크롤합니다.
- 반응형 중단점(
< 768px)이 데스크톱 드롭다운 팝오버를 터치 친화적인 바텀 액션 시트로 변환합니다. - 항목 텍스트, 단축키 힌트, 포커스 표시기 배경이 WCAG AA 대비(≥4.5:1)를 충족합니다.