HTML select 태그: 드롭다운·복수 선택과 전송 값 확인

HTML의 <select>는 option으로 만든 선택지 중 값을 고르는 양식 컨트롤입니다. 기본은 단일 선택이며 multiple로 복수 선택을 허용합니다. 서버로 보낼 항목 이름은 select의 name, 실제 값은 선택된 option의 value로 정합니다.

이름·표시 문구·전송 값 구분하기

label의 for와 select의 id를 같게 지정하면 선택 목록에 설명을 연결할 수 있습니다. id는 문서 안에서 요소를 식별하고 name은 제출 데이터의 키가 됩니다. option에 보이는 문구와 value는 다를 수 있으므로, 화면에서 “웹 개발”을 골라도 전송 값은 web이 될 수 있습니다. value를 생략하면 option의 텍스트가 값으로 사용됩니다.

단일 선택에서 selected를 생략하면 일반적으로 첫 사용 가능한 선택지가 초기 선택이 됩니다. 사용자가 반드시 선택하도록 하려면 아래 예제처럼 첫 선택지에 빈 value를 두고 required를 지정합니다. 안내 문구가 적혀 있어도 빈 값이면 필수 선택 조건을 충족하지 않습니다.

전체 예제: 필수 선택과 복수 선택 확인

아래 코드를 select-demo.html로 저장해 브라우저에서 엽니다. 제출 동작은 JavaScript로 막고 현재 양식 데이터를 페이지에 표시합니다. 실제 서버나 외부 사이트로 데이터를 보내지 않는 실습입니다.

<!doctype html>
<html lang="ko">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>select 값 확인</title>
  <style>
    body { max-width: 36rem; margin: 1rem auto; padding: 0 1rem; }
    label, select { display: block; margin-bottom: 0.5rem; }
    select, button { font: inherit; max-width: 100%; }
    pre { white-space: pre-wrap; overflow-wrap: anywhere; }
  </style>
</head>
<body>
  <h1>선택한 값 확인</h1>
  <form id="demo">
    <label for="topic">관심 주제 (필수)</label>
    <select id="topic" name="topic" required>
      <option value="" selected>주제를 선택하세요</option>
      <optgroup label="개발">
        <option value="web">웹 개발</option>
        <option value="data">데이터 처리</option>
      </optgroup>
    </select>
    <label for="skills">학습 기술 (복수 선택 가능)</label>
    <select id="skills" name="skills" multiple size="3">
      <option value="html" selected>HTML</option>
      <option value="css" selected>CSS</option>
      <option value="javascript">JavaScript</option>
    </select>
    <label for="locked">비활성 항목</label>
    <select id="locked" name="locked" disabled>
      <option value="sample">변경할 수 없음</option>
    </select>
    <button type="submit">값 확인</button>
    <button type="reset">초기화</button>
  </form>
  <pre id="result" aria-live="polite"></pre>
  <script>
    const form = document.getElementById('demo');
    const result = document.getElementById('result');
    form.addEventListener('submit', (event) => {
      event.preventDefault();
      const data = new FormData(form);
      result.textContent = JSON.stringify(Array.from(data.entries()), null, 2);
    });
    form.addEventListener('reset', () => { result.textContent = ''; });
  </script>
</body>
</html>
  1. 주제를 선택하지 않고 값 확인을 누릅니다. 브라우저의 필수 선택 검사가 제출을 막습니다.
  2. 웹 개발을 고르고 값 확인을 누릅니다. topic의 값 web과 skills의 값 html·css가 각각 표시됩니다. disabled인 locked는 제출 데이터에 포함되지 않습니다.
  3. 기술 선택을 바꾸고 다시 확인합니다. 선택한 항목마다 같은 이름인 skills가 반복됩니다. 선택을 모두 해제하면 skills 항목 자체가 없어질 수 있습니다.
  4. 초기화를 누르면 주제는 빈 안내 항목으로, 기술은 HTML·CSS로 돌아가고 결과 표시가 지워집니다.

multiple과 size는 서로 다른 속성입니다

multiple은 여러 값을 선택할 수 있게 하고 size는 화면에 표시할 행 수를 지정합니다. size를 키웠다고 자동으로 복수 선택이 되는 것은 아닙니다. 복수 선택의 키 조합은 운영체제에 따라 다릅니다. 데스크톱에서는 Ctrl 또는 Command와 클릭, Shift를 이용한 범위 선택을 사용할 수 있지만 모바일은 별도의 선택 화면을 보여줄 수 있습니다.

복수 선택 값을 JavaScript에서 읽을 때 select.value는 첫 선택 값만 나타냅니다. 전체 값은 selectedOptions를 순회하거나 FormData.getAll('skills')로 확인합니다. 서버에서도 같은 이름의 반복 항목을 받을 수 있도록 프레임워크의 파싱 규칙에 맞추어 처리합니다.

disabled·required·selected 사용 시 주의점

disabled는 조작을 막고 제출 데이터에서도 제외합니다. select에는 input의 readonly에 해당하는 기본 속성이 없으므로 readonly를 붙였다고 잠기지 않습니다. 화면에서 비활성화한 것만으로 서버의 권한 검사가 대체되는 것도 아닙니다.

required·disabled·multiple·selected는 불리언 속성입니다. selected="false"처럼 적어도 속성이 존재하므로 선택된 초기값으로 처리될 수 있습니다. 거짓으로 만들려면 해당 속성을 제거하거나 JavaScript의 대응 프로퍼티에 false를 지정합니다. reset은 현재 선택을 무조건 비우는 동작이 아니라 HTML에 선언한 초기 선택으로 돌아가는 동작입니다.

autofocus로 자동 포커스를 줄 수 있지만 사용자의 읽기 위치나 모바일 키보드 동작을 고려해 필요한 경우에만 사용합니다. 기본 선택 컨트롤의 모양과 팝업은 브라우저·운영체제에 따라 다르므로 일반적인 양식에는 label과 기본 키보드 조작을 유지하는 편이 유용합니다. 상세 규칙은 MDN select 문서와 MDN option 문서에서 확인할 수 있습니다.