폼에서 드롭다운 메뉴 최적화: 문제점과 CSS 해결법
프론트엔드 개발자들은 종종 드롭다운 높이가 4~5개 항목으로 고정된 select 요소를 마주한다. 이는 사용성 장벽을 만든다: 100개 이상의 선택지 중 하나를 빠르게 확인하려면 좁은 창 안에서 번거로운 스크롤링이 필요해지며, 결과적으로 사용자는 실망하고 효율성이 떨어진다. 결국 나쁜 사용자 경험으로 이어지며, 사용자는 선택지를 빠르게 스캔하거나 정보 기반 결정을 내리기 어렵다.
흔한 상황: '대상 독자'나 '허브' 같은 필드가 있는 블로그 게시물 제출 폼. 검색은 입력을 보완하지만, 전체 목록을 미리 보지 못하면 아무런 도움이 되지 않는다. 단순히 보기 위해 마우스 휠을 20~50번 돌려야 하는 상황은 지치고 시간 낭비다.
확장 가능한 드롭다운을 위한 CSS 해결책
해결 방법은 간단하다: 개발자 도구나 컴포넌트 스타일에 기본적인 CSS 규칙을 적용하면 된다. max-height: 80vh 또는 고정된 400~500px와 같이 합리적인 한계로 높이를 늘리면, 한 번에 20~30개의 항목을 표시할 수 있어 스크롤 피로도가 크게 줄어든다.
커스텀 또는 네이티브 select 요소용 예시 스타일:
.select-container {
position: relative;
}
.select-dropdown {
max-height: 80vh !important;
overflow-y: auto;
position: absolute;
z-index: 1000;
width: 100%;
background: white;
border: 1px solid #ccc;
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.select-option {
padding: 12px 16px;
cursor: pointer;
}
.select-option:hover {
background: #f5f5f5;
}
이 접근법은 레이아웃을 깨뜨리지 않으면서 가용 화면 공간을 효과적으로 활용한다. 대형 모니터에서는 특히 두드러지게 나타나며, 사용자는 즉시 전체 컨텍스트를 확인할 수 있다.
잘못된 패턴: 실제 데이터 크기 무시하기
고정된 크기의 드롭다운은 전형적인 UX 악습이다. 디자이너들은 3~5개 항목만 포함한 프로토타입을 만들고, 프론트엔드 개발자는 정교하게 구현하지만, 현실 데이터 부하를 고려하지 않는다. 그 결과, 실제 환경에서는 실패하는 인터페이스가 탄생한다.
이 악습의 주요 징후:
- 20개 이상의 옵션을 표시할 때 드롭다운 높이가 200px 미만인 경우.
- 긴 목록에 대해 가상 스크롤링이나 페이지네이션 없음.
- '전체 보기' 또는 전체 화면 모드 누락.
- 포커스 후에만 검색 기능 활성화되며, 미리보기 기능 없음.
대신 다음 개선 사항을 채택하자:
- 동적 높이:
min(80vh, 리스트의 50%) - 100개 이상 항목일 경우 가상화 (예:
react-window또는react-virtualized사용) - 퍼지 검색을 지원하는 키보드 탐색
- 스크롤 시 옵션을 지연 로딩
프론트엔드 개발의 최적 실천법
인터랙티브 컴포넌트는 뷰포트 크기에 따라 적응해야 한다. 정적 콘텐츠는 사용자를 끌어들이지 못하며, 접을 수 있거나 숨길 수 있어야 한다.
- 반응형 디자인: 모바일과 데스크톱 모두에서
max-height: calc(100vh - 200px)사용. - 접근성: ARIA 속성 추가 (
role="listbox",aria-activedescendant). - 성능: React/Vue에서는 z-index 충돌을 해결하기 위해 포털 사용.
- 테스트: 10개, 50개, 200개 항목을 포함한 리스트로 반드시 검증.
동적 드롭다운을 갖춘 예제 리액트 컴포넌트:
import React, { useState, useRef } from 'react';
const AdaptiveSelect = ({ options, onChange }) => {
const [isOpen, setIsOpen] = useState(false);
const [selected, setSelected] = useState('');
const dropdownRef = useRef();
const toggle = () => setIsOpen(!isOpen);
const handleSelect = (value) => {
setSelected(value);
onChange(value);
setIsOpen(false);
};
return (
<div className="select-container">
<div className="select-trigger" onClick={toggle}>
{selected || '옵션 선택'}
</div>
{isOpen && (
<div className="select-dropdown" ref={dropdownRef}>
{options.map(opt => (
<div key={opt} className="select-option" onClick={() => handleSelect(opt)}>
{opt}
</div>
))}
</div>
)}
</div>
);
};
export default AdaptiveSelect;
이 컴포넌트는 목록 크기와 화면 크기에 따라 자동 조정된다.
핵심 요약
- 확장성: 20개 이상의 옵션이 있는 드롭다운은 최적의 사용성을 위해
max-height: 80vh가 필요하다. - 사용자 경험: 스크롤 없이 전체 목록을 볼 수 있으면 선택 시간이 5~10배 빨라진다.
- 구현: 5~10줄의 CSS로 90%의 경우를 해결할 수 있으며, 복잡한 경우는 가상화 필요.
- 테스트: 항상 프로토타입의 4개 항목이 아닌 실제 데이터로 테스트해야 한다.
- A11y: 키보드 탐색과 스크린 리더 호환성 확보.
— Editorial Team
아직 댓글이 없습니다.