axi0motion

Pop select

A select chip whose list pops open from its corner while the highlight glides from row to row; it drives the real select underneath.

  • enhancer
  • select
  • dropdown
  • listbox
  • form
  • menu
  • since 0.2

Background Studio: tune it below, then copy the code

Your system asks for reduced motion: the demo shows its final state and nothing moves.

Live demo

Pop select example

Controls

Code

It follows the controls above: change an option and the code changes with it.

<link rel="stylesheet" href="/axi0/motion/motion.css?v=6">
<script src="/axi0/motion/motion.js?v=10" defer></script>

<label for="sort-by">Sort by</label>
<select id="sort-by" data-motion="pop-select">
  <option>Newest first</option>
  <option>Oldest first</option>
  <option>Most liked</option>
  <option>Most discussed</option>
  <option>Title, A to Z</option>
</select>

The wrappers: PopSelect.tsx (React, TypeScript) and PopSelect.vue (Vue). Both render the same attributes as the HTML; the loader does the rest.

Options

AttributeDefaultWhat it does
data-motion-placementautowhere the list opens (auto: below, or above when there is more room there)

Accessibility

- The chip is a select-only combobox (role="combobox", aria-expanded, aria-controls) named by the page's own label; the list is a listbox of options with aria-selected, and aria-activedescendant follows the highlight. - Closed: Down, Up, Enter or Space opens it; Home and End open it at the ends; typing opens it at the first match. Open: Up, Down, Home, End, Page Up and Page Down move the highlight; Enter, Space or Alt+Up picks; Tab picks and moves on; Escape closes without a change. Typed letters jump to the next match (the same letter again cycles). - Focus never leaves the chip. Clicking the label focuses it, clicking outside closes the list. - It sets the real select's value and fires its input and change events, so forms submit as before. Without JavaScript the plain select shows. - The chip is as wide as its widest option, so picking never moves what is beside it. Reduced motion shows every state at once, with no movement, and stops anything that would move on its own. Frame loops and CSS animations pause off screen and in hidden tabs. Only transform, opacity and paint animate, so nothing around it moves.

Size

pop-select.js is 2.8 KB gzip, with components-kit.js 3.9 KB it needs. A page loads the loader (2.7 KB) and core.js (1.4 KB) once, whatever it uses.