User Rating 0.0
Total Usage 0 times
Used for hidden input name & element IDs
#6C8EBF
Is this tool helpful?

Your feedback helps us improve.

About

Native <select> elements offer limited styling control across browsers. Border radius, padding, option height, font styling, and background colors render inconsistently between Chrome, Firefox, and Safari. This converter transforms a standard <select> into a semantic <ul>/<li> structure with full ARIA attributes (role="listbox", aria-selected, aria-expanded) preserved. The generated code requires zero external dependencies. It handles keyboard navigation (Arrow keys, Enter, Escape), click-outside dismissal, and screen reader announcements natively.

Failure to implement proper ARIA roles when replacing native form controls breaks accessibility compliance under WCAG 2.1 SC 4.1.2 (Name, Role, Value). This tool generates the complete accessible markup so the converted list behaves identically to a native select for assistive technology users. The output includes a hidden <input type="hidden"> that syncs the selected value for form submission compatibility. Note: this approach approximates native select behavior. Edge cases like <optgroup> nesting and mobile OS-level select pickers are not replicated.

select to list html select converter custom dropdown ul li dropdown form element converter accessible select css select replacement

Formulas

The conversion algorithm maps each child element of the source <select> to a corresponding list node:

map(<select>) <div class="custom-select">
map(<optioni) <li role="option" data-value=vi>ti</li>

Where vi = the value attribute of option i, and ti = the textContent of option i. The selected state is tracked via a state variable s where s {v0, v1, vn}.

The hidden input synchronization rule ensures form compatibility:

<input type="hidden">.value s on each selection change

ARIA state propagation follows:

forEach(lii) aria-selected =
{
TRUE if vi = sFALSE otherwise

Reference Data

FeatureNative <select>Converted <ul> List
Custom font stylingPartial (varies by OS)Full control
Custom option heightNot supportedFull control via CSS
Background colors per optionLimited (Firefox only)Full control
Border radiusOuter onlyInner and outer
Animations / transitionsNoneCSS transitions supported
Icons inside optionsNot supportedHTML content allowed
Search / filterNot nativeImplementable
Keyboard navigationNative (Arrow, Enter)Must implement manually
Screen reader supportNative role="listbox"Requires explicit ARIA attrs
Form submissionNative name/valueHidden input sync required
Mobile native pickerOS-level pickerNot available (custom dropdown)
<optgroup> supportNativeMust implement as nested list
multiple attributeNative multi-selectCheckbox list pattern
Cross-browser consistencyLow (major differences)High (CSS-controlled)
Tab order / focusNative tabindexRequires tabindex="0"
disabled stateNative attributearia-disabled="true" + CSS
required validationNative constraintCustom validation logic
Max visible optionssize attributemax-height + overflow-y
Right-to-left (RTL)Inherited from dirMust set dir="rtl" on container
Print renderingShows selected valueShows selected value (with print CSS)

Frequently Asked Questions

The generated code includes a hidden input element (<input type="hidden" name="...">) that automatically syncs its value attribute whenever the user selects a list item. When the parent form submits, the hidden input transmits the selected value identically to how a native select would. The name attribute is preserved from the original select configuration.
The container <ul> must carry role="listbox" and aria-labelledby pointing to a visible label. Each <li> needs role="option" and aria-selected="true" or "false". The trigger button requires aria-expanded and aria-haspopup="listbox". The active descendant is tracked via aria-activedescendant on the listbox for keyboard navigation announcements.
Yes. The generated JavaScript implements Arrow Up/Down to move focus between options, Enter or Space to select the focused option and close the dropdown, Escape to close without changing selection, and Home/End to jump to first/last option. Tab moves focus away from the component entirely, matching native select behavior per WAI-ARIA Listbox pattern specifications.
The generated code is static - it outputs the list based on the options defined at conversion time. To add options dynamically, you would append new <li role="option"> elements to the <ul> and register click handlers on them. The tool does not generate a dynamic mutation observer, but the output code structure is simple enough to extend with a few lines.
CSS can style the closed state of a select (border, background, font) but cannot style individual <option> elements reliably across browsers. Chrome and Safari ignore background-color and padding on options entirely. The dropdown arrow is rendered by the OS and varies between platforms. If you need consistent option styling, custom icons, animations, or search filtering, a list-based replacement is the only cross-browser solution.
The generated CSS includes max-height with overflow-y: auto on the options container. The default max height is configurable in the tool (set via the Max Visible Options field). Scroll behavior is smooth. For lists exceeding approximately 200 options, consider adding a search/filter input - this tool does not generate that feature automatically but the markup supports it.