HTML에서 드롭다운 만드는 법
드롭다운 목록은 선택지마다 <option>이 있는 <select> 요소예요. 각 옵션의 value는 폼이 보내는 값이고, 태그 사이의 텍스트는 독자에게 보이는 부분이에요. 하나를 고르고 Submit을 눌러 보세요.
폼은 language=js를 보내요. select의 name과 선택된 옵션의 value예요. selected는 기본값을 정하고, 없으면 첫 번째 옵션이 선택돼요. 옵션에 value가 없으면 대신 텍스트가 전송돼요.
for와 id로(또는 감싸서) 라벨을 select에 연결하면, 라벨을 클릭했을 때 드롭다운에 포커스가 가고 스크린 리더도 이름을 알려 줘요.
select와 option 속성
| 요소 | 속성 | 하는 일 |
|---|---|---|
<select> | name | 값을 보낼 때 쓰는 키 |
<select> | required | 비어 있는 첫 placeholder 옵션이 아니라 진짜 옵션을 골라야 함 |
<select> | multiple | 여러 옵션을 고를 수 있음 |
<select> | size | 보이는 행 수(목록 상자로 바뀜) |
<select> | disabled | 드롭다운 전체가 꺼지고 전송되지 않음 |
<option> | value | 선택됐을 때 보내는 값 |
<option> | selected | 페이지가 로드될 때 선택된 상태 |
<option> | disabled | 보이지만 고를 수 없음 |
<optgroup> | label | 묶음의 제목 |
required와 함께 쓰는 placeholder 옵션
select에는 항상 값이 있어서, placeholder가 없으면 독자가 드롭다운을 건드리지도 않았는데 첫 번째 진짜 옵션이 전송돼요. 비어 있는 첫 옵션이 그걸 해결하고, required는 진짜 옵션을 고를 때까지 제출을 막아요.
고르기 전에 Continue를 눌러 보세요. 브라우저가 거부하고 항목을 선택하라고 해요. placeholder는 required가 비어 있다고 보는 value=""이고, 나라를 고른 뒤에 다시 선택할 수 없도록 disabled예요.
optgroup으로 옵션 묶기
<optgroup label="...">은 옵션 묶음 위에 제목을 둬요. 제목은 선택할 수 없어요.
묶음은 중첩할 수 없어요. 목록의 제목은 한 단계뿐이에요. <optgroup>에 disabled를 주면 그 안의 모든 옵션이 비활성화돼요.
다중 선택
multiple은 독자가 여러 옵션을 고를 수 있게 하고, 드롭다운을 목록 상자로 바꿔요. Ctrl(Mac에서는 Cmd)을 누른 채로 하나씩 추가하거나, Shift로 범위를 선택하세요.
폼은 skills=html과 skills=css를 보내요. 선택한 옵션마다 같은 이름이 한 번씩이에요. Ctrl+클릭 동작을 모르는 사람이 많으니, 옵션이 몇 개뿐이라면 체크박스 묶음이 쓰기 더 쉬워요.
JavaScript로 값 읽고 설정하기
select.value는 선택된 옵션의 값을 읽고 설정하고, change 이벤트는 독자가 다른 옵션을 고를 때 발생해요. 흔한 용도는 첫 번째 드롭다운에 따라 옵션이 바뀌는 두 번째 드롭다운이에요.
new Option(text, value)는 옵션을 만들어요. select.selectedIndex는 선택된 옵션의 위치이고, select.selectedOptions는 선택된 옵션 목록이라서 다중 선택을 읽을 때 써요.
셀렉트 박스 꾸미기
드롭다운의 열린 목록은 브라우저와 운영체제가 그려서 꾸밀 수 있는 부분이 거의 없어요. 닫힌 상자는 꾸밀 수 있어요. appearance: none은 기본 화살표를 없애고, 배경 이미지로 내 화살표를 그 자리에 넣어요.
끝쪽 padding을 더 줘서 긴 옵션 텍스트가 화살표 밑으로 들어가지 않게 자리를 남겨요. 버튼처럼 여기서도 font: inherit가 중요해요. select는 기본적으로 브라우저의 작은 폼 글꼴을 써요. 열린 목록의 옵션은 기본 모양을 유지해요. Chrome은 appearance: base-select를 켜면 열린 목록도 꾸밀 수 있고, 지원하지 않는 브라우저는 기본 목록을 보여 줘요. 모든 곳에서 완전히 제어하려면 ARIA로 직접 위젯을 만들어야 하는데, 보기보다 제대로 만들기가 훨씬 어려워요.
select, 라디오 버튼, datalist 중 무엇을?
| 쓸 것 | 언제 |
|---|---|
<select> | 긴 목록 중 하나를 고르거나 공간이 좁을 때 |
| 라디오 버튼 | 모두 보여야 하는 몇 개의 선택지 중 하나(HTML 라디오 버튼 참고) |
<datalist>가 있는 <input> | 추천은 하되 어떤 입력값이든 허용할 때 |
자주 하는 실수
- 필수 선택에 placeholder가 없음. 독자가 고르지 않았어도 첫 번째 진짜 옵션이 전송돼요.
- placeholder에 진짜 값을 줌.
value="none"같은 경우예요.required는 이걸 유효한 선택으로 봐요.value=""를 쓰세요. - 텍스트가 길거나 번역되는데
value없는 옵션을 씀. 서버는 보이는 텍스트를 받는데, 그건 언어에 따라 바뀌어요. - 옵션 몇 개에
multiple을 씀. 체크박스가 쓰기 더 쉬워요. - 옵션의
click을 들음.<select>의change를 쓰세요. 키보드로 바꿀 때도 발생해요. - 라벨이 없음. placeholder만 있는 select는 옵션을 고르고 나면 이름이 없어져요.
자주 묻는 질문
HTML에서 드롭다운 목록은 어떻게 만드나요?
선택지마다 <option>을 하나씩 넣어 <select>를 쓰세요. <select name="color"><option value="red">Red</option><option value="blue">Blue</option></select>처럼요. select에는 name과 <label>을 주세요.
select의 기본 옵션은 어떻게 정하나요?
그 옵션에 selected를 추가하세요. <option value="blue" selected>Blue</option>처럼요. 없으면 첫 번째 옵션이 선택돼요. JavaScript에서는 select.value = 'blue'로 설정하세요.
select에 placeholder를 넣으려면 어떻게 하나요?
첫 번째 옵션을 비우고 선택할 수 없게 만드세요. <option value="" disabled selected>Choose a country</option>처럼요. <select>에 required를 추가하면 진짜 옵션을 고를 때까지 폼을 보낼 수 없어요.
JavaScript에서 select의 선택된 값은 어떻게 가져오나요?
select.value가 선택된 옵션의 값이에요. 보이는 텍스트는 select.selectedOptions[0].text로 가져오고, 선택이 바뀔 때 반응하려면 change 이벤트를 들으세요. 다중 선택이라면 select.selectedOptions를 순회하세요.
select와 datalist는 무엇이 다른가요?
<select>는 목록에 있는 옵션만 허용해요. <datalist>가 있는 <input>은 입력하는 동안 옵션을 추천하지만 어떤 텍스트든 받아요. 답이 반드시 내가 준 것 중 하나여야 한다면 select를 쓰세요.