Skip to content
FormSubmit

HTML

HTML select dropdown: options, placeholder, required, multiple and styling

How to build an HTML select dropdown: option and optgroup, a placeholder option, required, multiple, datalist for free text, CSS styling and JavaScript.

5 min readUpdated Oct 9, 2026

An HTML select dropdown is a <select name="..."> containing one <option> per choice, where each option's value is submitted and its text is shown. For a placeholder, add a first option with value="" and disabled selected hidden, and put required on the select. Group long lists with <optgroup>, add multiple to allow several choices, and connect a <label>.

This guide covers building a select properly, the placeholder pattern, multiple selection, the datalist alternative for free text, styling, and reading the value in JavaScript. It's part of the HTML form elements reference.

A select dropdown in a form

topic-form.html
<form action="https://formsubmit.app/f/YOUR_FORM_ID" method="POST">
  <label for="topic">What can we help with?</label>
  <select id="topic" name="topic" required>
    <option value="" disabled selected hidden>Choose a topic</option>
    <option value="sales">Sales question</option>
    <option value="support">Technical support</option>
    <option value="billing">Billing</option>
    <option value="other">Something else</option>
  </select>

  <label for="email">Email</label>
  <input id="email" type="email" name="email" autocomplete="email" required>

  <label for="message">Message</label>
  <textarea id="message" name="message" rows="5" required></textarea>

  <input type="text" name="_gotcha" tabindex="-1" autocomplete="off" style="display:none">
  <button type="submit">Send</button>
</form>

If someone picks "Technical support", the form submits topic=support. The text is for people, and the value is a stable key for you. If an option has no value attribute, its text is submitted instead, which is fine for simple lists but breaks if you later reword the text.

Option and optgroup

<option> attributes you'll use:

AttributeWhat it does
valueWhat's submitted when this option is selected.
selectedPre-selects this option. Without it, the first option is selected.
disabledShown but can't be chosen.
labelAlternative display text. Rarely needed.

<optgroup label="..."> groups options under a heading that can't be selected. It's useful for long lists:

html
<label for="service">Service</label>
<select id="service" name="service">
  <optgroup label="Design">
    <option value="branding">Branding</option>
    <option value="web-design">Web design</option>
  </optgroup>
  <optgroup label="Development">
    <option value="frontend">Front-end</option>
    <option value="backend">Back-end</option>
  </optgroup>
</select>

Optgroups can't be nested. Use them for one level of grouping only.

The placeholder option pattern

A select always has a value. Without a placeholder, the first real option is pre-selected, and people who skip the field submit it without meaning to. The fix is a placeholder option:

html
<option value="" disabled selected hidden>Choose a topic</option>

Each attribute does one job:

  • value="" makes the placeholder an empty answer, so required treats it as "nothing chosen".
  • selected shows it when the page loads.
  • disabled stops people from re-selecting it after picking a real option.
  • hidden keeps it out of the open list in browsers that support it. It's optional.

For required to work with the placeholder, the placeholder must be the first option, and the select must not have multiple or a size greater than 1. Keep a visible <label> as well. The placeholder text disappears once something is chosen.

Multiple selection and size

multiple turns the dropdown into a list box where several options can be selected:

html
<label for="languages">Languages you speak</label>
<select id="languages" name="languages" multiple size="5">
  <option value="en">English</option>
  <option value="es">Spanish</option>
  <option value="fr">French</option>
  <option value="de">German</option>
  <option value="hi">Hindi</option>
</select>

size sets how many rows are visible. A multi-select sends one name=value pair per selected option, for example languages=en&languages=fr, and FormSubmit keeps multiple values for the same name.

On desktop, selecting several options needs Ctrl or Cmd held down, which many visitors don't know and which is easy to undo by accident. For fewer than about ten options, checkboxes are usually clearer. For a single choice from a handful of options, radio buttons show everything at once.

Datalist: suggestions with free text

A select only allows its listed options. When most people will pick a common answer but some need to type their own, use an input with a <datalist>:

html
<label for="role">Job title</label>
<input id="role" name="role" list="roles">
<datalist id="roles">
  <option value="Founder"></option>
  <option value="Developer"></option>
  <option value="Designer"></option>
  <option value="Marketing manager"></option>
</datalist>

The browser shows matching suggestions as people type, and the input submits whatever ends up in the box. Datalist presentation varies a lot between browsers, so treat it as a convenience, not a guarantee of valid input.

Styling a select

Native selects are hard to style consistently. This removes the platform look and adds a custom arrow while keeping the native control:

select.css
select {
  appearance: none;
  box-sizing: border-box;
  width: 100%;
  padding: 0.625rem 2.5rem 0.625rem 0.75rem;
  font: inherit;
  color: inherit;
  background-color: #fff;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='%236b7280'%3E%3Cpath d='M5.3 7.3a1 1 0 0 1 1.4 0L10 10.6l3.3-3.3a1 1 0 1 1 1.4 1.4l-4 4a1 1 0 0 1-1.4 0l-4-4a1 1 0 0 1 0-1.4z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
  background-size: 1.25rem;
  border: 1px solid #c4c9d4;
  border-radius: 0.5rem;
}

select:focus-visible {
  outline: 2px solid #4f46e5;
  outline-offset: 2px;
}

select[multiple] {
  background-image: none;
  padding-right: 0.75rem;
}
  • appearance: none removes the native arrow and styling so your own can replace it.
  • Right padding stops long option text from running under the arrow.
  • font: inherit matches the rest of your form.
  • The open list of options is still drawn by the browser or operating system. On phones that's a native picker, which is a good thing for usability.

Some browsers now support fully customisable selects, where the open list can be styled with CSS. Support is limited, so treat it as progressive enhancement on top of the styles above.

Reading a select in JavaScript

read-select.js
const select = document.getElementById("topic");

// The selected value ("" while the placeholder is showing)
console.log(select.value);

// The visible text of the selected option
console.log(select.selectedOptions[0]?.text);

// All selected values in a multi-select
const languages = [...document.getElementById("languages").selectedOptions]
  .map((option) => option.value);

// Or via FormData, which matches what would be submitted
const values = new FormData(select.form).getAll("languages");

// React to changes
select.addEventListener("change", () => {
  console.log("Topic is now", select.value);
});

// Set the selection
select.value = "billing";

A common pattern is to show extra fields based on the choice, for example revealing an order number input when the topic is "billing". Toggle the hidden attribute on a wrapper and set disabled on fields that don't apply, so they aren't submitted.

Sending the selected option

The chosen option arrives as a normal field, such as topic: support, so you can see at a glance what each message is about. Point the form at https://formsubmit.app/f/YOUR_FORM_ID with method="POST" and every submission is stored, spam-filtered and emailed to you. The full walkthrough is in how to send an HTML form to email. For other field types, see HTML input types or the HTML form elements overview.

Frequently asked questions

How do I add a placeholder to a select dropdown?

Make the first option a placeholder with an empty value, plus disabled and selected, for example Choose a topic. Add hidden as well to keep it out of the open list in browsers that support it. With required on the select, the form won't submit until a real option is picked.

What does a select submit?

The value attribute of the selected option. If an option has no value attribute, its text content is submitted instead. A select with multiple submits one name=value pair per selected option.

How do I let users select more than one option?

Add the multiple attribute. Desktop users then hold Ctrl or Cmd to pick several options, which many people don't know. For a short list, a group of checkboxes is usually easier to use.

How do I style the dropdown arrow?

Set appearance to none on the select to remove the native arrow, then add your own with a background-image and some right padding. The open list of options is still drawn by the browser and operating system.

Can a select allow free text?

No. A select only submits one of its options. For suggestions plus free text, use an input with a list attribute that points at a datalist element.

Keep reading

Your form backend is 60 seconds away

Sign up with Google or email, create a form, paste the endpoint. Free forever for small sites — no credit card.