unselect2

It quacks like a dropdown and it walks like a dropdown. It is not a dropdown — it is a real <select> wearing better clothes. The element you author stays in the page, keeps its name, and remains the single thing the form submits.

Nothing on this page touches a chain. There is no contract, no address, no transaction and no wallet — this is a browser component and a plain form post. The eight demos beside it on the demos page are contracts on Base Sepolia; this one is not, and its card carries no chain badge for that reason.

Watch: 30 seconds

The receipt

The native <select> cannot be styled. That is not an oversight in browsers, it is the design: the control is drawn by the operating system, which is also why it behaves correctly everywhere without anyone writing code. Taking that appearance back normally means replacing the element with a pile of <div>s, and the bill for that arrives in four parts.

The reason none of the first three lands on the visitor is the same reason in each case: the component enhances rather than replaces. It builds a styleable surface, puts it in front of the real element, and leaves the element to keep doing its job. The payload never stops being the browser's.

What it does on a touchscreen

It enhances there too, and that is a trade rather than a free win — so it is worth stating plainly. There is no touch branch anywhere in the component: no pointer-type test in the script, none in the stylesheet. A phone or tablet therefore gets the same panel a mouse gets, and the platform's own picker does not appear — no iOS wheel, no Android bottom sheet, and none of the affordances those bring with them. What survives is everything the receipt above is about: the value still lives in the <select>, the form still submits the same payload, and the panel is operable by touch. What is given up is the picker a phone user already knows. If that trade is the wrong one for a particular field, the enhancement is opt-in per element — leave data-unselect2 off and that field stays exactly as the browser drew it.


Try it

Three fields: two required, one optional, one of them grouped, and one row that is shown but cannot be chosen. Open a field with the mouse, or focus it and use the arrow keys, Home, End, or just start typing a letter.

Required. The last row is deliberately not selectable — open the field and try to reach it.

Required, and grouped. Type a letter with the field focused to jump to a row.

Optional. Leave it alone and the form still submits.


How to check the claims above

Provenance

The component is vendored into this site as two files copied verbatim — no package manager, no build step, no bundler. The copy is pinned to commit 419ba67 of the unselect2 repository, and a test in this repo hashes the vendored bytes against that commit, so an edit made here instead of upstream fails the build rather than shipping quietly.