HTML <select> reference Jump to this section

Common attributes Jump to this section

Basic select structure Jump to this section

A <select> element contains <option> elements that define the available choices. Users can choose one option from the dropdown (or multiple with the multiple attribute).

<select name="choice">
    <option value="">Choose...</option>
    <option value="1">Option 1</option>
    <option value="2">Option 2</option>
    <option value="3">Option 3</option>
</select>

name Jump to this section

Identifies the select element when submitting form data. The name becomes the key, and the selected option's value becomes the data.

Use descriptive names that match your backend expectations (e.g., country, category, size).

<select name="country">
    <option value="us">United States</option>
    <option value="ca">Canada</option>
    <option value="mx">Mexico</option>
</select>
<!-- Submits as: country=us (or whatever was selected) -->

multiple Jump to this section

Boolean attribute that allows users to select multiple options. Typically displayed as a scrollable list box instead of a dropdown. Users hold Ctrl/Cmd to select multiple items.

Use when users need to choose more than one option (e.g., selecting multiple interests, skills, or tags).

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

size Jump to this section

Specifies how many options to display at once. Without this attribute, a dropdown shows one option. With size, it displays as a scrollable list box.

Use with multiple to control the visible height of the list box.

<select size="3">
    <option>Apple</option>
    <option>Banana</option>
    <option>Cherry</option>
    <option>Date</option>
    <option>Elderberry</option>
</select>

required Jump to this section

Boolean attribute that makes the select element mandatory for form submission. The first option (if it has an empty value) will trigger validation if selected.

Use on fields that must have a selection. Pair with an empty placeholder option.

<select name="country" required>
    <option value="">Select a country</option>
    <option value="us">United States</option>
    <option value="ca">Canada</option>
</select>

disabled Jump to this section

Boolean attribute that makes the select non-interactive and excludes it from form submission. Typically displayed with reduced opacity.

Use when the select is temporarily unavailable or depends on another selection.

<select disabled>
    <option>Option 1</option>
    <option>Option 2</option>
</select>

autofocus Jump to this section

Automatically focuses the select when the page loads. Only one element per page should have this attribute.

Use sparingly on forms where the select is the primary action. Can disorient users if overused.

<select autofocus>
    <option>Choose an option</option>
</select>

autocomplete Jump to this section

Controls browser autofill behavior. Can specify what type of data the browser should suggest.

Common values: on, off, name, email, country, postal-code, tel, bday-day, bday-month, bday-year, cc-type, etc.

<select name="country" autocomplete="country">
    <option value="us">United States</option>
    <option value="ca">Canada</option>
</select>

<select autocomplete="off">
    <!-- Disable autocomplete -->
</select>

form Jump to this section

Associates the select with a form element by its id, even when the select is outside the form in the DOM.

<form id="user-form">
    <!-- other inputs -->
</form>

<select name="role" form="user-form">
    <option value="admin">Admin</option>
    <option value="user">User</option>
</select>

Option attributes Jump to this section

value Jump to this section

Specifies the value to submit when this option is selected. If omitted, the option's text content is used as the value.

<select name="size">
    <option value="s">Small</option>
    <option value="m">Medium</option>
    <option value="l">Large</option>
</select>
<!-- Selecting "Small" submits: size=s -->

<select name="color">
    <option>Red</option>
    <option>Blue</option>
</select>
<!-- Selecting "Red" submits: color=Red -->

selected Jump to this section

Boolean attribute that sets which option is selected by default when the page loads.

<select name="theme">
    <option value="light">Light</option>
    <option value="dark" selected>Dark</option>
    <option value="auto">Auto</option>
</select>
<!-- "Dark" is selected by default -->

disabled (option) Jump to this section

Boolean attribute that makes a specific option non-selectable. Useful for placeholder text or unavailable choices.

<select>
    <option disabled selected>Choose a color</option>
    <option value="red">Red</option>
    <option value="blue">Blue</option>
    <option value="green" disabled>Green (out of stock)</option>
</select>

label (option) Jump to this section

Provides alternative text for the option. If present, this is displayed instead of the option's content. Rarely used.

<option value="us" label="USA">United States of America</option>
<!-- Dropdown shows "USA" instead of full text -->

Optgroup attributes Jump to this section

<optgroup> Jump to this section

Groups related options together with a label. Creates visual separation in the dropdown. The label is not selectable.

<select name="fruit">
    <option value="">Choose a fruit</option>
    <optgroup label="Citrus">
        <option value="orange">Orange</option>
        <option value="lemon">Lemon</option>
    </optgroup>
    <optgroup label="Berries">
        <option value="strawberry">Strawberry</option>
        <option value="blueberry">Blueberry</option>
    </optgroup>
</select>

disabled (optgroup) Jump to this section

Boolean attribute that disables all options within the optgroup.

<optgroup label="Premium Features" disabled>
    <option value="feature1">Feature 1</option>
    <option value="feature2">Feature 2</option>
</optgroup>

aria-label Jump to this section

Provides an accessible label for the select when a visible <label> element isn't present.

<select aria-label="Choose your country">
    <option value="us">United States</option>
    <option value="ca">Canada</option>
</select>

aria-describedby Jump to this section

References additional descriptive text by its id to provide context or instructions.

<select id="country" aria-describedby="country-help">
    <option value="us">United States</option>
    <option value="ca">Canada</option>
</select>
<small id="country-help">Select your billing country</small>

aria-invalid Jump to this section

Indicates whether the select has a validation error. Should be updated dynamically with JavaScript.

<select aria-invalid="true" aria-describedby="error-msg">
    <option value="">Choose...</option>
</select>
<span id="error-msg">Please select an option</span>

aria-required Jump to this section

Indicates that the field is required. Use in addition to the required attribute for better accessibility.

<select required aria-required="true">
    <option value="">Choose...</option>
</select>

data-* attributes Jump to this section

Custom attributes for storing application-specific data on the select element.

<select data-category="location" data-validate="required">
    <option value="us">United States</option>
</select>

<script>
  const select = document.querySelector('select');
  const category = select.dataset.category; // "location"
  const validate = select.dataset.validate; // "required"
</script>

id Jump to this section

Unique identifier for the select. Essential for linking with <label> elements and JavaScript selection.

<label for="country">Country:</label>
<select id="country" name="country">
    <option value="us">United States</option>
</select>

class Jump to this section

Assigns CSS class names for styling or JavaScript selection.

<select class="form-control select-lg">
    <option>Option 1</option>
</select>

title Jump to this section

Provides a tooltip on hover. Not accessible to keyboard-only users or mobile, so don't rely on it for critical information.

<select title="Choose your preferred language">
    <option value="en">English</option>
    <option value="es">Spanish</option>
</select>

tabindex Jump to this section

Controls keyboard focus order. Select elements are focusable by default, so rarely needed.

<select tabindex="1">
    <option>First</option>
</select>
<select tabindex="2">
    <option>Second</option>
</select>

Styling basics Jump to this section

Select elements are notoriously difficult to style consistently across browsers. The native dropdown arrow and behavior are controlled by the browser. Modern approaches use appearance: none to remove default styling and add custom arrows.

Examples Jump to this section

Basic select Jump to this section

.select-basic {
    padding: 10px 14px;
    border: 1px solid #d1d5db;
    border-radius: 6px;
    font-size: 15px;
    width: 100%;
}

Custom arrow select Jump to this section

<div class="select-wrapper">
    <select class="select-custom">
        <option>Choose...</option>
        <option>Option 1</option>
        <option>Option 2</option>
    </select>
    <div class="select-arrow">▼</div>
</div>
.select-wrapper {
    position: relative;
    display: inline-block;
}
.select-custom {
    appearance: none;
    padding: 10px 40px 10px 14px;
    border: 1px solid #d1d5db;
    border-radius: 6px;
    width: 100%;
    background: white;
    cursor: pointer;
}
.select-arrow {
    position: absolute;
    right: 14px;
    top: 50%;
    transform: translateY(-50%);
    pointer-events: none;
    color: #6b7280;
}

Filled select (material style) Jump to this section

.select-filled {
    padding: 12px 14px;
    background: #f3f4f6;
    border: none;
    border-bottom: 2px solid #9ca3af;
    border-radius: 6px 6px 0 0;
    font-size: 15px;
}

Underline select Jump to this section

.select-underline {
    padding: 8px 0;
    background: transparent;
    border: none;
    border-bottom: 1px solid #d1d5db;
    font-size: 15px;
}

Pill select Jump to this section

.select-pill {
    padding: 10px 20px;
    border: 1px solid #d1d5db;
    border-radius: 50px;
    font-size: 15px;
}

Size variants Jump to this section

.select-small {
    padding: 6px 10px;
    font-size: 13px;
    border-radius: 4px;
}
.select-medium {
    padding: 10px 14px;
    font-size: 15px;
    border-radius: 6px;
}
.select-large {
    padding: 14px 18px;
    font-size: 17px;
    border-radius: 8px;
}

Disabled state Jump to this section

.select-basic:disabled {
    background: #f3f4f6;
    border-color: #e5e7eb;
    color: #9ca3af;
    cursor: not-allowed;
}

Error state Jump to this section

.select-error {
    border: 2px solid #dc2626;
    background: #fef2f2;
}

Success state Jump to this section

.select-success {
    border: 2px solid #16a34a;
    background: #f0fdf4;
}

Colored select Jump to this section

.select-colored {
    padding: 10px 14px;
    background: #3b82f6;
    color: white;
    border: none;
    border-radius: 6px;
    cursor: pointer;
}
/* Note: Options styling is limited in browsers */

With icon Jump to this section

🌍
<div style="position:relative;">
    <span class="icon">🌍</span>
    <select class="select-with-icon">
        <option>Choose country</option>
        <option>United States</option>
        <option>Canada</option>
    </select>
</div>
.select-with-icon {
    padding-left: 40px;
    /* other styles */
}
.icon {
    position: absolute;
    left: 12px;
    top: 50%;
    transform: translateY(-50%);
    pointer-events: none;
    color: #6b7280;
}

Focus states Jump to this section

Always provide clear focus indicators for accessibility. Use :focus pseudo-class.

Blue outline on focus Jump to this section

.select-basic {
    border: 1px solid #d1d5db;
    transition: all 0.2s;
}
.select-basic:focus {
    border-color: #3b82f6;
    outline: 2px solid #93c5fd;
    outline-offset: 2px;
}

Glow effect on focus Jump to this section

.select-glow {
    border: 1px solid #d1d5db;
    transition: all 0.2s;
}
.select-glow:focus {
    border-color: #8b5cf6;
    box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.1);
    outline: none;
}

Styling optgroups Jump to this section

select optgroup {
    font-weight: 600;
    color: #6b7280;
    font-style: normal;
}
select option {
    padding-left: 20px;
}

JavaScript patterns Jump to this section

Select elements are commonly used for filtering, navigation, and form inputs. Use event listeners to respond to selection changes and manipulate options dynamically.

Getting and setting selected value Jump to this section

Access the current selected value using the value property.

const select = document.getElementById('js-value');
// Get the selected value
const value = select.value;
// Set a specific value
select.value = '2'; // Selects "Option 2"
// Get the selected option element
const selectedOption = select.options[select.selectedIndex];
const text = selectedOption.textContent;

Listen for changes Jump to this section

Use the change event to respond when the user selects a different option.

No selection
const select = document.getElementById('js-change');
const output = document.getElementById('js-change-output');
select.addEventListener('change', (e) => {
    const value = e.target.value;
    const text = e.target.options[e.target.selectedIndex].text;
    output.textContent = `You selected: ${text} (${value})`;
});

Dynamically populate options Jump to this section

Create and add options programmatically from an array of data.

const select = document.getElementById('js-populate');
// Your data (could be from an API)
const countries = [
    { code: 'us', name: 'United States' },
    { code: 'ca', name: 'Canada' },
    { code: 'mx', name: 'Mexico' },
    { code: 'uk', name: 'United Kingdom' }
];
// Clear existing options
select.innerHTML = '';
// Add new options
countries.forEach(country => {
    const option = document.createElement('option');
    option.value = country.code;
    option.textContent = country.name;
    select.appendChild(option);
});

Dependent dropdowns Jump to this section

Update the second dropdown based on the first dropdown's selection.

<select id="category">
    <option value="">Choose category</option>
    <option value="fruits">Fruits</option>
    <option value="vegetables">Vegetables</option>
</select>
<select id="item" disabled>
    <option>Select category first</option>
</select>
const categorySelect = document.getElementById('category');
const itemSelect = document.getElementById('item');
const items = {
    fruits: ['Apple', 'Banana', 'Orange'],
    vegetables: ['Carrot', 'Broccoli', 'Spinach']
};
categorySelect.addEventListener('change', (e) => {
    const category = e.target.value;
    // Clear and disable if no category
    if (!category) {
        itemSelect.innerHTML = '';
        itemSelect.disabled = true;
        return;
    }
    // Enable and populate items
    itemSelect.disabled = false;
    itemSelect.innerHTML = '';
    items[category].forEach(item => {
        const option = document.createElement('option');
        option.value = item.toLowerCase();
        option.textContent = item;
        itemSelect.appendChild(option);
    });
});

Redirect on selection Jump to this section

Navigate to a different page when an option is selected. Common for navigation menus.

const navSelect = document.getElementById('js-redirect');
navSelect.addEventListener('change', (e) => {
    const url = e.target.value;
    if (url) {
        // Navigate to the selected page
        window.location.href = url;
        // Or for demonstration, just alert
        // alert(`Would navigate to: ${url}`);
        // Reset to placeholder
        e.target.value = '';
    }
});

Filter/search options Jump to this section

Allow users to search through options by typing (enhanced select functionality).

<input id="search" type="text" placeholder="Search...">
<select id="searchable" size="5">
    <option value="apple">Apple</option>
    <option value="banana">Banana</option>
    <option value="cherry">Cherry</option>
    <option value="date">Date</option>
    <option value="elderberry">Elderberry</option>
    <option value="fig">Fig</option>
    <option value="grape">Grape</option>
</select>
const searchInput = document.getElementById('search');
const select = document.getElementById('searchable');
const allOptions = Array.from(select.options);
searchInput.addEventListener('input', (e) => {
    const searchTerm = e.target.value.toLowerCase();
    // Clear select
    select.innerHTML = '';
    // Filter and re-add matching options
    allOptions.forEach(option => {
        if (option.textContent.toLowerCase().includes(searchTerm)) {
            select.appendChild(option.cloneNode(true));
        }
    });
    // Show message if no matches
    if (select.options.length === 0) {
        const noMatch = document.createElement('option');
        noMatch.textContent = 'No matches found';
        noMatch.disabled = true;
        select.appendChild(noMatch);
    }
});

Get all selected values (multiple) Jump to this section

When using multiple attribute, retrieve all selected values as an array.

const multiSelect = document.getElementById('js-multiple');
// Get all selected values as an array
const selectedValues = Array.from(multiSelect.selectedOptions)
    .map(option => option.value);
console.log(selectedValues); // ['html', 'css', ...]
// Or get selected text
const selectedText = Array.from(multiSelect.selectedOptions)
    .map(option => option.textContent);

Remove option dynamically Jump to this section

Remove specific options based on conditions or user actions.

const select = document.getElementById('js-remove');
// Remove by index
select.remove(2); // Removes the 3rd option
// Remove by value
Array.from(select.options).forEach((option, index) => {
    if (option.value === '2') {
        select.remove(index);
    }
});
// Remove selected option
if (select.selectedIndex > -1) {
    select.remove(select.selectedIndex);
}

Add option dynamically Jump to this section

Add new options to the select on the fly.

const select = document.getElementById('js-add');
// Create a new option
const option = document.createElement('option');
option.value = 'new-value';
option.textContent = 'New Option';
// Add it to the select
select.appendChild(option);
// Optionally select it
select.value = 'new-value';
// Or insert at specific position
select.insertBefore(option, select.options[1]);

Save and restore selection Jump to this section

Save user's selection to localStorage and restore it on page load.

Selection persists across page reloads
const select = document.getElementById('js-persist');
const storageKey = 'theme-preference';
// Restore saved selection on load
const saved = localStorage.getItem(storageKey);
if (saved) {
    select.value = saved;
}
// Save selection on change
select.addEventListener('change', (e) => {
    localStorage.setItem(storageKey, e.target.value);
});

Validate selection Jump to this section

Ensure a valid option is selected before form submission.

<form id="validate-form">
    <select id="validate">
        <option value="">Choose an option</option>
        <option value="1">Option 1</option>
        <option value="2">Option 2</option>
    </select>
    <button type="submit">Submit</button>
    <div id="error"></div>
</form>
const form = document.getElementById('validate-form');
const select = document.getElementById('validate');
const error = document.getElementById('error');
form.addEventListener('submit', (e) => {
    e.preventDefault();
    if (!select.value) {
        error.textContent = 'Please select an option';
        select.style.borderColor = '#dc2626';
        select.focus();
        return;
    }
    error.textContent = '';
    select.style.borderColor = '#d1d5db';
    alert('Form submitted!');
});
select.addEventListener('change', () => {
    error.textContent = '';
    select.style.borderColor = '#d1d5db';
});

Disable/enable options dynamically Jump to this section

Enable or disable specific options based on conditions.

<label>
    <input type="checkbox" id="toggle" checked>
    Enable "Option 2"
</label>
<select id="select">
    <option>Option 1</option>
    <option>Option 2</option>
    <option>Option 3</option>
</select>
const checkbox = document.getElementById('toggle');
const select = document.getElementById('select');
checkbox.addEventListener('change', (e) => {
    // Disable/enable Option 2 (index 1)
    select.options[1].disabled = !e.target.checked;
    // If Option 2 was selected and now disabled, reset
    if (!e.target.checked && select.selectedIndex === 1) {
        select.selectedIndex = 0;
    }
});

Sort options alphabetically Jump to this section

Dynamically sort select options in alphabetical order.

const select = document.getElementById('js-sort');
// Get all options except the first (placeholder)
const options = Array.from(select.options).slice(1);
// Sort alphabetically
options.sort((a, b) => a.text.localeCompare(b.text));
// Clear select and re-add sorted options
select.innerHTML = '<option value="">Choose...</option>';
options.forEach(option => select.appendChild(option));