Customizable select
Style the <select> dropdown with pseudo-elements
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>
/* 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".