10 · Customizable select

Customizable select

Style the <select> dropdown with pseudo-elements

Chrome 135+ · experimental
← Index

Styled <select>

The new appearance: base-select activates customizable mode: the button, dropdown and options are 100% styleable.

select, ::picker(select) { appearance: base-select }

::picker(select)

The pseudo-element that renders the dropdown surface: it lives in the top layer, with its own shadows, borders and spacing.

::picker(select) { box-shadow: 0 8px 24px rgba(0,0,0,.5) }

<selectedcontent>

The <selectedcontent> element automatically mirrors the chosen option's content into the select button.

<button><selectedcontent></selectedcontent></button>

css
/* activa el modo customizable */
.nice-select,
.nice-select::picker(select) {
  appearance: base-select;
}

/* el botón del select */
.nice-select button {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
}

/* refleja la opción elegida */
.nice-select selectedcontent {
  flex: 1;
  text-align: left;
}

/* el dropdown — entra animado con @starting-style */
.nice-select::picker(select) {
  opacity: 0;
  transform: translateY(-8px) scale(.96);
  transition: opacity .25s, transform .25s,
              overlay .25s allow-discrete,
              display .25s allow-discrete;
}
.nice-select:open::picker(select) {
  opacity: 1;
  transform: translateY(0) scale(1);
}
@starting-style {
  .nice-select:open::picker(select) {
    opacity: 0;
    transform: translateY(-8px) scale(.96);
  }
}

/* stagger de las options con sibling-index() */
.nice-select option {
  transition-delay: calc(sibling-index() * .06s);
}
@starting-style {
  .nice-select:open option {
    opacity: 0;
    transform: translateX(20px);
  }
}

An honest note on support

Many of these APIs are recent and not yet in every browser (see the pill on each section). The nice part is they all degrade gracefully: the carousel still scrolls, the accordion opens/closes, the textarea works — just without the animated "plus".