Radios · short

Short list

Up to 10 entries the radios stay visible. Arrow keys move, digits pick directly.

Shipping
<fieldset data-gridselect>
  <legend>Shipping</legend>
  <label><input type="radio" name="ship" value="std" checked> Standard</label>
  …
</fieldset>

gridselect(document.querySelector("[data-gridselect]"));
Checkboxes · short

Multiple choice

Checkbox groups work the same way. Space or a digit toggles.

Extras
Radios · filter

Long list with filter

More than 10 entries: a compact field opens a panel. Type to filter (try dollar or zur), arrows move through the grid, Enter or a digit picks.

Currency
Radios · highlight

Long list with highlight

Items never move, matches are marked. Good for lists people use every day.

Currency
<fieldset data-gridselect data-search="highlight"> … </fieldset>
Layouts

Grid or flow

The default grid makes every column as wide as the widest entry, so short labels get as many columns as fit. data-layout="flow" lets the entries run one after another like chips, as dense as possible; arrow up and down jump to the nearest entry in the row above or below.

Country (grid, columns fit the widest name)
Currency (flow)
<fieldset data-gridselect> … </fieldset>                     <!-- grid, the default -->
<fieldset data-gridselect data-layout="flow"> … </fieldset>
Groups

Groups with headings

Options in <optgroup> get a heading in the panel, and each group starts a new row. The heading stays at the top while its group scrolls by. Works the same with items and <grid-select>.

<select name="currency">
  <optgroup label="Europe">
    <option value="EUR">Euro (EUR)</option> …
  </optgroup>
  <optgroup label="Americas"> … </optgroup>
</select>
Pinned · recent

Favourites on top

Pinned entries and the last picks appear on top with their own digits. They stay in the list as well, so positions there never change. Recent picks are stored in this browser only.

Currency
<fieldset data-gridselect data-pinned="EUR,USD" data-recent="currency"> … </fieldset>
Descriptions

A second line

Entries can carry a description under the label (description in items, data-description on an option). Screen readers hear it after the name. With data-search-description the search finds capitals too: try paris.

Country
Multiple · long

Pick several

Checkbox groups and <select multiple> get the same panel. Items toggle, the panel stays open, so you can filter and pick several in a row. data-max="3" stops at three: the rest is locked until you untick one.

Watchlist (up to 3)
Element · grid-select

As a custom element

Import @emmgeede/gridselect/element and write HTML. Works in plain pages and in React, Vue, Svelte or Angular.

<grid-select name="destination" label="Destination">
  <option value="">Choose a destination…</option>
  <option value="BER">Berlin (BER)</option>
  …
</grid-select>

import "@emmgeede/gridselect/element";
Layout · list

Long labels

data-layout="list" stacks the items in one column.

Text module
Select · source

From a plain select

An existing <select> keeps working in your form. The empty first option becomes the placeholder.