Выпадающие списки в HTML: select, option, optgroup — шаг за шагом (HTML)

Выпадающий список — один из самых распространённых элементов форм. Он занимает мало места, привычен пользователю и позволяет выбрать один или несколько вариантов из заранее заданного набора. В HTML для его создания используется связка трёх тегов: select как контейнер, option как пункт списка и optgroup для группировки пунктов.


Шаг 1. Базовый список через select и option

Минимальный выпадающий список состоит из тега <select>, внутри которого размещены один или несколько тегов <option>. Каждый <option> — это отдельный пункт, который увидит пользователь.

html
<label for="city">Город доставки:</label>
<select id="city" name="city">
  <option value="omsk">Омск</option>
  <option value="moscow">Москва</option>
  <option value="spb">Санкт-Петербург</option>
</select>

Что здесь происходит:

  • <select> создаёт сам элемент управления. Атрибут name нужен, чтобы сервер получил значение при отправке формы.
  • Каждый <option> имеет атрибут value — именно он отправляется на сервер, а не тот текст, который видит пользователь. Текст между открывающим и закрывающим тегом — это подпись пункта в интерфейсе.
  • <label for="city"> связывает текстовую подпись с элементом через совпадение for и id. Это важно для доступности: клик по подписи открывает список.

Шаг 2. Пункт по умолчанию

Если не задать выбранный пункт явно, браузер выберет первый <option>. Чтобы задать другой, добавьте атрибут selected:

html
<select id="city" name="city">
  <option value="omsk">Омск</option>
  <option value="moscow" selected>Москва</option>
  <option value="spb">Санкт-Петербург</option>
</select>

В этом списке при загрузке страницы будет выбрана Москва.

Заглушка-подсказка

Часто первым пунктом ставят подсказку — например, «Выберите город» — и делают её невыбираемой или просто оставляют без value:

html
<select id="city" name="city">
  <option value="" selected disabled>— Выберите город —</option>
  <option value="omsk">Омск</option>
  <option value="moscow">Москва</option>
  <option value="spb">Санкт-Петербург</option>
</select>

Атрибут disabled делает пункт недоступным для выбора, а selected выделяет его по умолчанию. Пользователь видит подсказку, но не может её выбрать. Атрибут value="" гарантирует, что при отправке формы, если пользователь ничего не выбрал, поле будет пустым.


Шаг 3. Группировка пунктов через optgroup

Когда пунктов много, их удобно сгруппировать. Для этого используется тег <optgroup>. Он визуально разделяет пункты и добавляет заголовок группы.

html
<select id="city" name="city">
  <optgroup label="Сибирь">
    <option value="omsk">Омск</option>
    <option value="novosibirsk">Новосибирск</option>
    <option value="krasnoyarsk">Красноярск</option>
  </optgroup>
  <optgroup label="Центр">
    <option value="moscow">Москва</option>
    <option value="spb">Санкт-Петербург</option>
    <option value="voronezh">Воронеж</option>
  </optgroup>
</select>
  • Атрибут label у <optgroup> задаёт заголовок группы. Он отображается в списке, но не является выбираемым пунктом.
  • <optgroup> может содержать только <option>. Вкладывать <optgroup> друг в друга нельзя — поддерживается только один уровень.

Отключение целой группы

Атрибут disabled на <optgroup> делает все пункты внутри недоступными:

html
<optgroup label="Недоступно" disabled>
  <option value="a">Пункт A</option>
  <option value="b">Пункт B</option>
</optgroup>

Шаг 4. Множественный выбор

По умолчанию select позволяет выбрать только один пункт. Атрибут multiple включает выбор нескольких:

html
<select id="skills" name="skills" multiple>
  <option value="html">HTML</option>
  <option value="css">CSS</option>
  <option value="js">JavaScript</option>
  <option value="python">Python</option>
</select>

Нюансы множественного выбора:

  • Пользователь выбирает несколько пунктов, удерживая Ctrl (Windows) или Cmd (macOS), либо перетаскивая мышь.
  • Визуально список раскрывается на полную высоту, а не сворачивается в одну строку. Это часто неудобно, поэтому multiple применяют там, где он действительно нужен.
  • На сервер значение передаётся как массив. Для этого атрибут name часто пишут со скобками: name="skills[]".
  • Для предустановленного выбора нескольких пунктов атрибут selected ставится на каждый нужный <option>.

Шаг 5. Отправка данных на сервер

При отправке формы select передаёт значение атрибута value выбранного <option>. Если у выбранного <option> нет value, отправляется его текстовое содержимое.

html
<!-- Отправится "msk" -->
<option value="msk">Москва</option>
 
<!-- Отправится "Москва" -->
<option>Москва</option>

Рекомендуется всегда задавать value явно — это делает данные предсказуемыми и не зависящими от изменений текста в интерфейсе.


Шаг 6. Стилизация: что можно, а что сложно

Стилизация select — известная боль фронтенд-разработки. Браузеры по-разному отображают раскрывающийся список и стрелку, и не все части элемента можно оформить через CSS.

Что контролируется легко:

  • Шрифт, размер, цвет фона и рамки закрытого списка — через стандартные свойства CSS.
  • Отступы и общие размеры через padding, width, height.
  • Цвет текста пунктов в большинстве браузеров.

Что контролируется с ограничениями:

  • Кастомная стрелка — через скрытие нативной и замену на фоновое изображение или псевдоэлемент. Но в разных браузерах подходы отличаются.
  • Стилизация раскрывшегося списка — в Chrome и Firefox часть свойств применяется к <option>, но в Safari возможности сильно ограничены.

Что почти не контролируется:

  • Внешний вид всплывающего списка в Safari и на мобильных устройствах: там используется системный интерфейс, и CSS почти не влияет.

Если требуется полный контроль над внешним видом, вместо нативного <select> часто делают кастомный компонент на JavaScript с <div>, <button> и aria-атрибутами. Но у такого подхода есть цена: нужно вручную реализовывать навигацию с клавиатуры, доступность для скринридеров и поведение при закрытии по клику вне списка.


Шаг 7. Доступность

Нативный <select> хорошо поддерживается скринридерами «из коробки», но несколько правил нужно соблюдать:

  • Всегда связывайте <select> с <label> через for и id. Скринридер озвучит подпись перед элементом.
  • Не используйте placeholder через пустой <option> без disabled — пользователь может его отправить, и данные будут некорректными.
  • Если список обязателен, добавьте required — это включит встроенную валидацию браузера:
html
<select id="city" name="city" required>
  <option value="" disabled selected>— Выберите город —</option>
  <option value="omsk">Омск</option>
  <option value="moscow">Москва</option>
</select>
  • Атрибут aria-label можно использовать, если видимой подписи нет, но явный <label> предпочтительнее.

Шаг 8. Сборка всего вместе

Пример формы с группированным списком, заглушкой и множественным выбором:

html
<form action="/submit" method="post">
  <p>
    <label for="city">Город доставки:</label>
    <select id="city" name="city" required>
      <option value="" disabled selected>— Выберите город —</option>
      <optgroup label="Сибирь">
        <option value="omsk">Омск</option>
        <option value="novosibirsk">Новосибирск</option>
      </optgroup>
      <optgroup label="Центр">
        <option value="moscow">Москва</option>
        <option value="spb">Санкт-Петербург</option>
      </optgroup>
    </select>
  </p>
 
  <p>
    <label for="skills">Дополнительные услуги:</label>
    <select id="skills" name="skills[]" multiple size="4">
      <option value="pack">Упаковка</option>
      <option value="insurance">Страховка</option>
      <option value="express">Срочная доставка</option>
    </select>
  </p>
 
  <p><button type="submit">Отправить</button></p>
</form>

В этом примере:

  • Первый список обязателен, сгруппирован по регионам и имеет заглушку.
  • Второй список допускает множественный выбор, атрибут size="4" задаёт высоту — показываются четыре пункта одновременно.
  • Атрибут name="skills[]" указывает серверу, что ожидается массив значений.

Итог

Тег / атрибут Назначение
<select> Контейнер выпадающего списка
name Имя поля для отправки на сервер
multiple Разрешает выбор нескольких пунктов
required Обязательное поле
size Число видимых пунктов без прокрутки
<option> Пункт списка
value Значение, отправляемое на сервер
selected Выбран по умолчанию
disabled Недоступен для выбора
<optgroup> Группа пунктов с заголовком
labeloptgroup) Заголовок группы

Добавить комментарий