Выпадающий список в HTML: полное руководство по тегам <select> и <option> с примерами

Выбираем из предложенных вариантов

Выпадающий список в HTML: полное руководство по тегам <select> и <option> с примерами

Выпадающий список в HTML добавляют, когда пользователю нужно что-то выбрать: способ доставки, язык интерфейса или любимую пиццу. Такой список полезен тем, что экономит место, убирает лишний ввод и даёт готовый набор вариантов. Главное — настроить его так, чтобы он был удобным, доступным и вёл себя предсказуемо во всех браузерах. Разберёмся, как это сделать и какие есть хитрости.

Что такое выпадающий список в HTML

В HTML есть несколько способов спросить у пользователя, чего он хочет. Но когда вариантов много, а вводить от себя ничего не нужно, то используют <select>.

Основное назначение элемента <select>

Представьте, что вы делаете форму заказа товаров и у вас есть список из 20 городов, куда их можно доставить. Если дать человеку текстовое поле, то он может написать «Масква» или «СПбб» (или СБП) и тем самым сломает вам всю логику. Решает эту проблему <select> : вы заранее задаёте допустимые варианты, а пользователю остаётся только кликнуть, выбрать и двигаться дальше.

Главная задача <select> — сделать выбор простым и быстрым. Пользователь не тратит время на набор текста и не делает ошибок, а вы получаете ровно то значение, которое нужно.

Отличие выпадающего списка от других форм ввода

HTML-форма может собирать ответы разными способами:

  • Текстовое поле (<input type="text"> или <textarea>) — полная свобода. Но и риск получить вместо города доставки смайлики или что-то ещё тоже полный.
  • Чекбоксы и радиокнопки — хороши для пары-тройки вариантов. Но если их десятки, страница превращается в бесконечную портянку, которую прокручиваешь, как ленту в соцсетях.

<select> же — это компактный, управляемый элемент. Открыл, выбрал, закрыл. При регистрации, например, просто докручиваете до Kazakhstan или вводите первые буквы — и всё. А текстовое поле в такой ситуации только подарит вам коллекцию Kazakstan, «Казакстан» и ещё десяток авторских вариаций.

Как создать выпадающий список (<select>)

Начнём с разбора ключевых частей. 

Базовый синтаксис

По сути, <select> — это контейнер, внутри которого находится набор вариантов для выбора. Сам контейнер задаётся открывающим <select> и закрывающим </select> тегами.

Внутри располагаются теги <option>. Каждый <option> — это отдельный пункт в списке. Текст между тегами <option> — то, что видит пользователь в выпадающем меню. Атрибут value — это уже техническая часть: именно его значение уходит на сервер при отправке формы.

Базовая разметка выпадающего списка будет такой:

<form action="#">
      <label for="lang">Language</label>
      <select name="languages" id="lang">
        <option value="javascript">JavaScript</option>
        <option value="php">PHP</option>
        <option value="java">Java</option>
        <option value="golang">Golang</option>
        <option value="python">Python</option>
        <option value="C++">C++</option>
      </select>
      <input type="submit" value="Submit" />
</form>
Как создать выпадающий список (<select>)

Если пользователь выберет Python, на сервер отправится python. Это удобно: на экране можно написать что угодно — хоть на японском, хоть с эмодзи — а в value оставить стабильное, понятное бэкенду значение.

Обязательные атрибуты: name, id, value

Чтобы <select> не просто красиво располагался на странице, а реально работал, у него и его пунктов должны быть правильно проставлены ключевые атрибуты.

  • name — имя поля формы. Без него сервер просто не получит выбранное значение, потому что не будет знать, к какому полю оно относится.
  • id — уникальный идентификатор элемента на странице. Чаще всего нужен для связи с <label> или для обращения к элементу через JavaScript.

    Например:
    <select name="languages" id="lang">
  • value (у каждого <option>) — то, что отправляется на сервер при выборе этого пункта. Если атрибут не задан, браузер отправит текст из содержимого <option>:
    <option value="python">Python</option>

Настройка пунктов списка (<option>)

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

Атрибуты <option>

Дальше рассмотрим три основных атрибута.

value (значение для отправки на сервер)

То, что форма передаст бэкенду. Пользователь видит одно (например, «Курьером до двери»), а сервер получает другое (courier). Это удобно, если отображаемый текст может меняться или быть на разных языках, а бэкенд всегда работает с чёткими, стабильными значениями.

<select>
  <option value="pickup">Самовывоз из магазина</option>
  <option value="courier">Курьером до двери</option>
  <option value="post">Доставка почтой</option>
</select>

Даже если потом вы переименуете «Курьером до двери» в «Экспресс-доставка» — бэкенд всё равно получит courier и не сломается.

Если value не указать, браузер возьмёт текст внутри <option>. Это может сработать, но лучше всегда задавать value явно — так вы избежите сюрпризов, если поменяли надпись для пользователя, а бэкенд всё ещё ждёт старое значение.

selected (выбранный по умолчанию пункт)

Если хотите, чтобы при загрузке страницы сразу стояло нужное значение, то ставьте selected на нужный <option>. Это особенно полезно, если у вас есть «самый популярный» выбор или если нужно подтянуть значение из прошлых действий пользователя.

<option value="latte">Латте</option>
<option value="espresso" selected>Эспрессо</option>
<option value="americano">Американо</option>

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

Атрибуты<option>

disabled (неактивный пункт)

Иногда в списке нужно показать вариант, который сейчас недоступен для выбора. Причин может быть много: товар временно закончился, пункт появится только при определённых условиях или он используется как «заглушка» или заголовок внутри списка.

В таком случае в нужный <option> добавляют атрибут disabled — и браузер сделает этот пункт неактивным:

<option value="tea">Чай</option>
<option value="coffee" disabled>Кофе (нет в наличии)</option>
<option value="juice">Сок</option>
Атрибуты<option>

👉 Если используете такой пункт как плейсхолдер в начале списка, давайте ему пустое value и атрибут selected. Так он будет отображаться первым, но выбрать его нельзя, и в форму он ничего не отправит:

<option value="" disabled selected>-- Выберите напиток --</option>
Атрибуты<option>

Группировка пунктов через <optgroup>

Бывает, что список получается длинным и разнородным. Чтобы пользователь не утонул в сотне вариантов, их можно разбить на категории.

Для этого есть тег <optgroup> — он работает только внутри <select> и содержит внутри себя обычные <option>. Заголовок группы задаётся атрибутом label. Такой заголовок будет отображаться как «некликабельный» раздел, а все пункты под ним — уже обычные варианты.

<select name="menu">
  <optgroup label="Горячие напитки">
    <option value="tea">Чай</option>
    <option value="coffee">Кофе</option>
  </optgroup>
  <optgroup label="Холодные напитки">
    <option value="cola">Кола</option>
    <option value="juice">Сок</option>
  </optgroup>
</select>
Атрибуты<option>

Визуально браузер сам отделит группы и покажет их названия. Пользователю проще будет сориентироваться, а вы избежите «бесконечного» списка.

Расширенные возможности

Иногда <select> нужно «прокачать», чтобы он умел чуть больше, чем просто выбрать один пункт. Тут можно использовать разные дополнительные фишки, которые открывают новые сценарии.

Множественный выбор (multiple)

По умолчанию <select> даёт выбрать только один вариант. Но что, если вы делаете форму, где человек должен указать все языки, на которых он пишет код? Тут пригодится атрибут multiple, он проставляется в теге <select>.

<form action="#">
  <label for="langs">Выберите языки программирования</label>
<!-- Добавляем возможность выбрать несколько вариантов -->
  <select name="languages" id="langs" multiple>
    <option value="js">JavaScript</option>
    <option value="py">Python</option>
    <option value="java">Java</option>
    <option value="php">PHP</option>
    <option value="go">Go</option>
  </select>
  <input type="submit" value="Отправить" />
</form>
Атрибуты<option>

С ним <select> превращается в мини-чек-лист: можно зажать Ctrl (или Cmd на Mac) и кликать по нужным пунктам, выделяя сразу несколько. Внешний вид может немного различаться в зависимости от браузера, но выбранные элементы будут подсвечены или отмечены галочками.

👉 Если вариантов много, добавьте понятный плейсхолдер или лейбл, чтобы пользователю было ясно, что можно выбрать несколько позиций.

Автозаполнение (datalist)

Иногда хочется дать пользователю свободу ввода, но при этом предложить список готовых значений. Для этого есть отдельный тег <datalist>. Это не <select>, а отдельный элемент, который работает в связке с обычным <input>.

Синтаксис простой: вместо <select> мы ставим <input> с атрибутом list, а сам список вариантов выносим в <datalist> с соответствующим id. Пока пользователь печатает, браузер показывает выпадающие подсказки из этого списка.

Почти как настоящий автокомплит — вроде свободный ввод, а вроде и готовый список под рукой.

<form action="#">
  <label for="browser">Выберите браузер</label>
  <input list="browsers" name="browser" id="browser">
  <datalist id="browsers">
    <option value="Chrome">
    <option value="Firefox">
    <option value="Safari">
    <option value="Edge">
    <option value="Opera">
  </datalist>
  <input type="submit" value="Отправить" />
</form>
Атрибуты<option>

<datalist> не ограничивает ввод — пользователь всё равно может написать что угодно. Но готовые варианты помогут избежать опечаток и упростят выбор.

Стилизация выпадающего списка

<select> по умолчанию не самый привлекательный элемент на веб-странице. Браузеры рисуют его по-своему, и без CSS он выглядит ну так себе. Но внешний вид можно поменять. Правда, есть нюансы: <select> относится к сложным для стилизации элементам, потому что у каждого браузера свои правила.

CSS-оформление (границы, фон, шрифты)

К тегу <select> можно применить стандартные CSS-свойства, чтобы изменить его внешний вид. Самое простое — поменять шрифт, фон, цвет текста и границы. Это работает без проблем:

Например:

   select {
     /* Шрифт и базовый размер текста */
     font-family: 'Segoe UI', Tahoma, sans-serif;
     font-size: 16px;
     /* Цвет текста и фон */
     color: #333;
     background-color: #fff;
     /* Рамка и скруглённые углы */
     border: 1px solid #ccc;
     border-radius: 6px;
     /* Отступы: справа больше места для стрелки */
     padding: 10px 40px 10px 12px;
     /* Фиксированная ширина*/
     width: 220px;
     /* Лёгкая тень для объёма */
     box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
   }
Стилизация выпадающего списка

Всегда ставьте box-sizing: border-box, чтобы отступы и границы не растягивали элемент непредсказуемо.

Как изменить стрелку раскрытия

Хотя <select> и можно базово стилизовать, у него есть ограничения — из‑за различий между браузерами и особенностей рендеринга этих элементов. Допустим, не всегда получится полностью изменить внешний вид стрелки выпадающего списка. У <select> стрелка — это встроенная часть элемента, и просто через background-image её не подменишь. Нужно «отключить» стандартный вид и нарисовать свой:

select {
   /* Сбрасываем стандартный стиль */
  appearance: none; 
  -webkit-appearance: none;
  -moz-appearance: none;
   /* Добавляем и выравниваем стрелку */
  background: url('arrow.svg') no-repeat right 5px center / 10px;
}
Стилизация выпадающего списка

Safari и Firefox не всегда корректно отображают кастомную стрелку, поэтому обязательно проверяйте, как элемент выглядит в каждом браузере. Иногда приходится добавлять обёртку <div> и рисовать стрелку псевдоэлементом.

Псевдоклассы (:hover, :focus)

Помимо этого, можно использовать CSS-псевдоклассы, чтобы добавить интерактивности. Например, менять фон при наведении или подсветку рамки при фокусе:

   select:hover {
     background-color: #abb8c3;
   }
   select:focus {
     /* жёлтый акцент */
     border-color: #d6fb51;
     /* убираем стандартную синюю обводку */
     outline: none;
   }
Стилизация выпадающего списка

Практические примеры

Выпадающий список стран с поиском

Обычный <select> в HTML не умеет искать по списку. Если у вас там более 200 пунктов (например, список стран), прокручивать всё вручную — боль.

Но можно подключить JS-библиотеку, которая превратит стандартный длинный <select> в красивый и удобный элемент с поиском и автодополнением. Самые популярные варианты:

  • Select2 — классика на jQuery, куча настроек, локализация, подгрузка данных с сервера.
  • Chosen — лёгкий и старый, но до сих пор рабочий вариант.
  • Selectize.js — на чистом JS, можно подключить поиск, теги, автокомплит.
  • Choices.js — современный вариант без jQuery, лёгкий и кастомизируемый.

Принцип работы у всех примерно одинаковый:

  1. Подключаете CSS и JS библиотеки (через CDN или локально).
  2. Даёте обычному <select> id или класс.
  3. Инициализируете плагин в JS, указывая настройки (плейсхолдер, сортировку, мультивыбор, автоподгрузку и т. д.).

Пример с Chosen:

Выпадающий список стран с поиском

Многоуровневый список (категории и подкатегории)

Иногда нужно не просто разделить список на группы (<optgroup>), а сделать зависимые списки: выбираешь нужную категорию — и дальше подгружаются подкатегории. Например, выбрали категорию «Техника», а во втором списке появились подкатегории «Смартфоны» и «Ноутбуки».

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

<label for="category">Категория</label>
<select id="category">
  <option value="">Выберите категорию...</option>
  <option value="tech">Техника</option>
  <option value="clothes">Одежда</option>
</select>
<label for="subcategory">Подкатегория</label>
<select id="subcategory">
  <option value="">Сначала выберите категорию</option>
</select>
Многоуровневый список (категории и подкатегории)

Тут пока всё статично: подкатегории не меняются. Чтобы они подгружались динамически, подключим JavaScript.

Связка с JavaScript (динамическое обновление)

Для начала создаём объект subcategories — в нём будут лежать списки подкатегорий для каждой категории:

 const subcategories = {
    tech: [
      { value: 'smartphones', text: 'Смартфоны' },
      { value: 'laptops', text: 'Ноутбуки' }
    ],
    clothes: [
      { value: 'mens', text: 'Мужская одежда' },
      { value: 'womens', text: 'Женская одежда' }
    ]
  };

Дальше мы вешаем обработчик на первый <select> (category), чтобы отлавливать изменение выбора:

// Находим первый <select> с категориями по id
 document.getElementById('category').addEventListener('change', function () {
 // Находим второй <select> для подкатегорий
 const subcatSelect = document.getElementById('subcategory');

Затем будем делать так: каждый раз очищаем второй список и вставляем новые <option> в зависимости от выбранной категории.

// Очищаем старые варианты подкатегорий
subcatSelect.replaceChildren(); 
// Берём value выбранной категории
const selected = this.value; 
if (subcategories[selected]) {
  // Создаём новые <option> и добавляем в <select>
  subcategories[selected].forEach(opt => {
    subcatSelect.add(new Option(opt.text, opt.value));
  });
} else {
  // Заглушка, если категория не выбрана
  subcatSelect.add(new Option('Сначала выберите категорию', ''));
}
Связка с JavaScript (динамическое обновление)

Что в итоге происходит:

  1. Пользователь выбирает категорию в первом списке.
  2. Скрипт ловит это событие и очищает второй список.
  3. Если категория есть в subcategories, туда загружаются соответствующие подкатегории.
  4. Если нет — остаётся заглушка «Сначала выберите категорию».

Частые ошибки и решения

Почему список не отправляет данные на сервер

В 90% случаев причина банальная: у <select> нет атрибута name. Без него браузер просто не отправит значение в форму.

<!-- name обязателен -->
<select name="country"> 
  <option value="ru">Russia</option>
</select>

Ещё момент: если в <option> нет value, то на сервер улетит текст внутри тега. Так что не ленимся и всегда прописываем value.

Но бывают и другие проблемы:

  • <select> не добавлен в <form>.
  • Нет кнопки отправки с type="submit". Без неё форма просто не улетит.
  • JavaScript что-то перехватывает или ломает отправку. Например, обработчик события submit вызывает event.preventDefault() и останавливает стандартную отправку, а потом забывает вручную отправить данные. В итоге <select> тут вообще ни при чём — проблема в логике скрипта.
  • Серверная часть не ждёт или неправильно обрабатывает параметр.

Короче: проверьте, что <select> внутри <form>, у него есть name, есть нормальная кнопка для отправки, а JS и сервер настроены правильно.

Как сделать обязательный выбор (required)

Если нужно, чтобы пользователь обязательно выбрал что-то из списка, — ставим атрибут required. Но первый пункт списка должен иметь пустой value, иначе браузер подумает, что выбор уже сделан.

 <form>
   <select id="category" name="category" required>
     <option value="">--Выберите категорию--</option>
     <option value="tech">Техника</option>
     <option value="clothes">Одежда</option>
     <option value="books">Книги</option>
   </select>
   <button type="submit">Отправить</button>
 </form>
Как сделать обязательный выбор (required)

При required и пустом значении браузер выдаст ошибку, если нажать «Отправить». После выбора любого другого пункта форма отправится нормально.

Проблемы с отображением в мобильных браузерах

Хотя современные браузеры более-менее одинаково обрабатывают <select>, сюрпризы всё ещё бывают. Особенно на мобильных устройствах, где браузер может навязать свой нативный вид списка.

Чтобы список выглядел и работал предсказуемо:

  • Нормализуйте стили. CSS reset или normalize.css уберут сильные расхождения в стилях по умолчанию между браузерами.
  • Тестируйте везде. Chrome, Firefox, Safari, Edge — и на всех платформах: Windows, macOS, iOS, Android. На айфоне <select> почти всегда будет выглядеть иначе, чем в десктопном Safari.
  • Проверяйте поддержку CSS. Если используете свежие свойства (например, кастомные тени или скругления), добавляйте вендорные префиксы (-webkit-, -moz-), чтобы не было сюрпризов.

Иногда проще оставить нативный вид <select> в мобильных браузерах и сосредоточиться на UX, чем пытаться его вылизать каждый пиксель.

Бонус для читателей

Если вам интересно погрузиться в мир ИТ и при этом немного сэкономить, держите наш промокод на курсы Практикума. Он даст вам скидку при оплате, поможет с льготной ипотекой и даст безлимит на маркетплейсах. Ладно, окей, это просто скидка, без остального, но хорошая. 

Вам слово

Приходите к нам в соцсети поделиться своим мнением о статье и почитать, что пишут другие. А ещё там выходит дополнительный контент, которого нет на сайте — шпаргалки, опросы и разная дурка. В общем, вот тележка, вот ВК — велком!

Обложка:

Алексей Сухов

Корректор:

Александр Зубов

Вёрстка:

Мария Климентьева

Соцсети:

Юлия Зубарева

Вам может быть интересно
easy