0Support

CSS customizable select playground

Explore the new customizable select surface with rich option content, picker, icon, and checkmark styling, plus an optional fallback for browsers without support.

Read the guide

Ask AI

CSS customizable select playground

Response generated with openai/gpt-5.4-nano. AI can make mistakes. Always review the result.
HTML
<form class="custom-select-demo">
  <label for="language-select">Primary programming language</label>
  <select class="language-select" id="language-select" name="language">
    <button>
      <selectedcontent></selectedcontent>
    </button>
      <option value="javascript" data-language="javascript">
        <span class="language-option" data-language="javascript">
          <span class="logo" data-logo="JS" aria-hidden="true"></span>
          <span class="language-copy">
            <span class="name">JavaScript</span>
            <span class="meta" data-meta="Frontend runtime"></span>
          </span>
        </span>
      </option>
      <option value="typescript" data-language="typescript" selected>
        <span class="language-option" data-language="typescript">
          <span class="logo" data-logo="TS" aria-hidden="true"></span>
          <span class="language-copy">
            <span class="name">TypeScript</span>
            <span class="meta" data-meta="Static typing"></span>
          </span>
        </span>
      </option>
      <option value="python" data-language="python">
        <span class="language-option" data-language="python">
          <span class="logo" data-logo="Py" aria-hidden="true"></span>
          <span class="language-copy">
            <span class="name">Python</span>
            <span class="meta" data-meta="Scripting and data"></span>
          </span>
        </span>
      </option>
      <option value="rust" data-language="rust">
        <span class="language-option" data-language="rust">
          <span class="logo" data-logo="Rs" aria-hidden="true"></span>
          <span class="language-copy">
            <span class="name">Rust</span>
            <span class="meta" data-meta="Safe systems"></span>
          </span>
        </span>
      </option>
      <option value="go" data-language="go">
        <span class="language-option" data-language="go">
          <span class="logo" data-logo="Go" aria-hidden="true"></span>
          <span class="language-copy">
            <span class="name">Go</span>
            <span class="meta" data-meta="Concurrent services"></span>
          </span>
        </span>
      </option>
  </select>
</form>
Tailwind CSS
Some classes with arbitrary values can be replaced by native classes, depending on the value and your Tailwind CSS configuration.
<form class="grid gap-[0.55rem] inline-[min(100%,_28rem)]">
  <label class="[color:color-mix(in_oklch,_currentColor_72%,_transparent)] [font-weight:750]" for="language-select">Primary programming language</label>
  <select class="inline-fit max-inline-full [font:inherit] text-[#f8fafc] supports-[appearance:base-select]:[appearance:base-select] supports-[appearance:base-select]:[&::picker(select)]:[appearance:base-select] supports-[appearance:base-select]:flex supports-[appearance:base-select]:items-center supports-[appearance:base-select]:gap-[10px] supports-[appearance:base-select]:[padding-block:12px] supports-[appearance:base-select]:[padding-inline:16px] supports-[appearance:base-select]:[border:1px_solid_color-mix(in_oklch,_#8b5cf6_52%,_transparent)] supports-[appearance:base-select]:rounded-[18px] supports-[appearance:base-select]:bg-[#111827] supports-[appearance:base-select]:text-[#f8fafc] supports-[appearance:base-select]:shadow-[0_1rem_2.5rem_color-mix(in_oklch,_#8b5cf6_28%,_transparent)] supports-[appearance:base-select]:[&_selectedcontent]:contents supports-[appearance:base-select]:[&_.language-option]:flex supports-[appearance:base-select]:[&_.language-option]:items-center supports-[appearance:base-select]:[&_.language-option]:gap-[10px] supports-[appearance:base-select]:[&_.language-option]:min-inline-max supports-[appearance:base-select]:[&::picker-icon]:[content:''] supports-[appearance:base-select]:[&::picker-icon]:[display:block] supports-[appearance:base-select]:[&::picker-icon]:inline-[1rem] supports-[appearance:base-select]:[&::picker-icon]:block-[0.65rem] supports-[appearance:base-select]:[&::picker-icon]:flex-none supports-[appearance:base-select]:[&::picker-icon]:bg-current supports-[appearance:base-select]:[&::picker-icon]:[clip-path:polygon(0_0,_50%_58%,_100%_0,_100%_42%,_50%_100%,_0_42%)] supports-[appearance:base-select]:[&::picker-icon]:[translate:0.3125rem] supports-[appearance:base-select]:[&::picker-icon]:[transition:transform_0.2s_ease-out] supports-[appearance:base-select]:[&:open::picker-icon]:[transform:rotateX(180deg)] supports-[appearance:base-select]:[&::picker(select)]:[margin-block-start:0.45rem] supports-[appearance:base-select]:[&::picker(select)]:[padding:0.38rem] supports-[appearance:base-select]:[&::picker(select)]:[border:1px_solid_color-mix(in_oklch,_#8b5cf6_46%,_transparent)] supports-[appearance:base-select]:[&::picker(select)]:rounded-[18px] supports-[appearance:base-select]:[&::picker(select)]:bg-[#111827] supports-[appearance:base-select]:[&::picker(select)]:text-[#f8fafc] supports-[appearance:base-select]:[&::picker(select)]:shadow-[0_1.25rem_3rem_color-mix(in_oklch,_#8b5cf6_32%,_black_18%)] supports-[appearance:base-select]:[&::picker(select)]:opacity-0 supports-[appearance:base-select]:[&::picker(select)]:[translate:0_-0.35rem] supports-[appearance:base-select]:[&::picker(select)]:[transition:opacity_0.2s_ease,_translate_0.2s_ease,_display_0.2s_allow-discrete,_overlay_0.2s_allow-discrete] supports-[appearance:base-select]:[&::picker(select)]:inline-fit supports-[appearance:base-select]:[&::picker(select)]:[min-inline-size:anchor-size(width)] supports-[appearance:base-select]:[&::picker(select)]:[max-inline-size:min(28rem,_calc(100vi_-_2rem))] supports-[appearance:base-select]:[&:open::picker(select)]:opacity-100 supports-[appearance:base-select]:[&:open::picker(select)]:[translate:0_0] supports-[appearance:base-select]:starting:[&:open::picker(select)]:opacity-0 supports-[appearance:base-select]:starting:[&:open::picker(select)]:[translate:0_-0.35rem] supports-[appearance:base-select]:[&_option]:flex supports-[appearance:base-select]:[&_option]:items-center supports-[appearance:base-select]:[&_option]:gap-[10px] supports-[appearance:base-select]:[&_option]:[padding-block:10px] supports-[appearance:base-select]:[&_option]:[padding-inline:14px] supports-[appearance:base-select]:[&_option]:rounded-[12px] supports-[appearance:base-select]:[&_option]:bg-transparent supports-[appearance:base-select]:[&_option]:text-[#f8fafc] supports-[appearance:base-select]:[&_option]:[transition:background-color_0.2s_ease,_color_0.2s_ease] supports-[appearance:base-select]:[&_option:hover]:[background:color-mix(in_oklch,_#8b5cf6_22%,_transparent)] supports-[appearance:base-select]:[&_option:focus-visible]:[background:color-mix(in_oklch,_#8b5cf6_22%,_transparent)] supports-[appearance:base-select]:[&_option:checked]:[background:color-mix(in_oklch,_#8b5cf6_34%,_transparent)] supports-[appearance:base-select]:[&_option::checkmark]:[content:'✓'] supports-[appearance:base-select]:[&_option::checkmark]:grid supports-[appearance:base-select]:[&_option::checkmark]:place-items-center supports-[appearance:base-select]:[&_option::checkmark]:inline-[1.45rem] supports-[appearance:base-select]:[&_option::checkmark]:block-[1.45rem] supports-[appearance:base-select]:[&_option::checkmark]:flex-none supports-[appearance:base-select]:[&_option::checkmark]:order-2 supports-[appearance:base-select]:[&_option::checkmark]:[margin-inline-start:0.35rem] supports-[appearance:base-select]:[&_option::checkmark]:rounded-full supports-[appearance:base-select]:[&_option::checkmark]:bg-[#8b5cf6] supports-[appearance:base-select]:[&_option::checkmark]:text-[#111827] supports-[appearance:base-select]:[&_option::checkmark]:font-extrabold supports-[appearance:base-select]:[&_.logo]:grid supports-[appearance:base-select]:[&_.logo]:place-items-center supports-[appearance:base-select]:[&_.logo]:inline-[34px] supports-[appearance:base-select]:[&_.logo]:block-[34px] supports-[appearance:base-select]:[&_.logo]:rounded-[0.75rem] supports-[appearance:base-select]:[&_.logo]:[background:var(--logo-bg)] supports-[appearance:base-select]:[&_.logo]:[color:var(--logo-color)] supports-[appearance:base-select]:[&_.logo]:font-black supports-[appearance:base-select]:[&_.logo]:tracking-normal supports-[appearance:base-select]:[&_.logo::before]:[content:attr(data-logo)] supports-[appearance:base-select]:[&_.logo::before]:text-[0.72em] supports-[appearance:base-select]:[&_.language-copy]:grid supports-[appearance:base-select]:[&_.language-copy]:gap-[0.08rem] supports-[appearance:base-select]:[&_.language-copy]:min-inline-max supports-[appearance:base-select]:[&_.name]:font-extrabold supports-[appearance:base-select]:[&_.name]:leading-[1.1] supports-[appearance:base-select]:[&_.name]:whitespace-nowrap supports-[appearance:base-select]:[&_.meta]:text-[0.78rem] supports-[appearance:base-select]:[&_.meta]:[color:color-mix(in_oklch,_currentColor_70%,_transparent)] supports-[appearance:base-select]:[&_.meta]:leading-[1.1] supports-[appearance:base-select]:[&_.meta]:whitespace-nowrap supports-[appearance:base-select]:[&_.meta::before]:[content:attr(data-meta)] not-supports-[appearance:base-select]:[appearance:none] not-supports-[appearance:base-select]:[padding-block:12px] not-supports-[appearance:base-select]:[padding-inline:16px_calc(16px_+_1.75rem)] not-supports-[appearance:base-select]:[border:1px_solid_color-mix(in_oklch,_#8b5cf6_52%,_transparent)] not-supports-[appearance:base-select]:rounded-[18px] not-supports-[appearance:base-select]:[background:#111827_url('data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22%23f8fafc%22%3E%3Cpath%20stroke%3D%22none%22%20d%3D%22M0%200h24v24H0z%22%20fill%3D%22none%22%2F%3E%3Cpath%20d%3D%22M18.707%208.293a1%201%200%200%201%200%201.414l-6%206a1%201%200%200%201-1.414%200l-6-6a1%201%200%200%201%201.414-1.414L12%2013.586l5.293-5.293a1%201%200%200%201%201.414%200%22%2F%3E%3C%2Fsvg%3E')_right_0.625rem_center_/_1.5rem_no-repeat] not-supports-[appearance:base-select]:text-[#f8fafc]" id="language-select" name="language">
    <button>
      <selectedcontent></selectedcontent>
    </button>
  <option value="javascript" data-language="javascript">
    <span class="language-option" data-language="javascript">
      <span class="logo [--logo-bg:#f7df1e] [--logo-color:#1f2937]" data-logo="JS" aria-hidden="true"></span>
      <span class="language-copy">
        <span class="name">JavaScript</span>
        <span class="meta" data-meta="Frontend runtime"></span>
      </span>
    </span>
  </option>
  <option value="typescript" data-language="typescript" selected>
    <span class="language-option" data-language="typescript">
      <span class="logo [--logo-bg:#3178c6] [--logo-color:#f8fafc]" data-logo="TS" aria-hidden="true"></span>
      <span class="language-copy">
        <span class="name">TypeScript</span>
        <span class="meta" data-meta="Static typing"></span>
      </span>
    </span>
  </option>
  <option value="python" data-language="python">
    <span class="language-option" data-language="python">
      <span class="logo [--logo-bg:#3776ab] [--logo-color:#fff7d6]" data-logo="Py" aria-hidden="true"></span>
      <span class="language-copy">
        <span class="name">Python</span>
        <span class="meta" data-meta="Scripting and data"></span>
      </span>
    </span>
  </option>
  <option value="rust" data-language="rust">
    <span class="language-option" data-language="rust">
      <span class="logo [--logo-bg:#f97316] [--logo-color:#111827]" data-logo="Rs" aria-hidden="true"></span>
      <span class="language-copy">
        <span class="name">Rust</span>
        <span class="meta" data-meta="Safe systems"></span>
      </span>
    </span>
  </option>
  <option value="go" data-language="go">
    <span class="language-option" data-language="go">
      <span class="logo [--logo-bg:#00add8] [--logo-color:#06202a]" data-logo="Go" aria-hidden="true"></span>
      <span class="language-copy">
        <span class="name">Go</span>
        <span class="meta" data-meta="Concurrent services"></span>
      </span>
    </span>
  </option>
  </select>
</form>
CSS
.custom-select-demo {
  display: grid;
  gap: 0.55rem;
  inline-size: min(100%, 28rem);
}

.custom-select-demo > label {
  color: color-mix(in oklch, currentColor 72%, transparent);
  font-weight: 750;
}

.language-select {
  inline-size: fit-content;
  max-inline-size: 100%;
  font: inherit;
  color: #f8fafc;
}

@supports (appearance: base-select) {
  .language-select,
  .language-select::picker(select) {
    appearance: base-select;
  }

  .language-select {
    display: flex;
    align-items: center;
    gap: 10px;
    padding-block: 12px;
    padding-inline: 16px;
    border: 1px solid color-mix(in oklch, #8b5cf6 52%, transparent);
    border-radius: 18px;
    background: #111827;
    color: #f8fafc;
    box-shadow: 0 1rem 2.5rem color-mix(in oklch, #8b5cf6 28%, transparent);
  }

  .language-select selectedcontent {
    display: contents;
  }

  .language-select .language-option {
    display: flex;
    align-items: center;
    gap: 10px;
    min-inline-size: max-content;
  }

  .language-select::picker-icon {
    content: '';
    display: block;
    inline-size: 1rem;
    block-size: 0.65rem;
    flex: none;
    background: currentColor;
    clip-path: polygon(0 0, 50% 58%, 100% 0, 100% 42%, 50% 100%, 0 42%);
    translate: 0.3125rem;
    transition: transform 0.2s ease-out;
  }

  .language-select:open::picker-icon {
    transform: rotateX(180deg);
  }

  .language-select::picker(select) {
    margin-block-start: 0.45rem;
    padding: 0.38rem;
    border: 1px solid color-mix(in oklch, #8b5cf6 46%, transparent);
    border-radius: 18px;
    background: #111827;
    color: #f8fafc;
    box-shadow: 0 1.25rem 3rem color-mix(in oklch, #8b5cf6 32%, black 18%);
    opacity: 0;
    translate: 0 -0.35rem;
    transition: opacity 0.2s ease, translate 0.2s ease, display 0.2s allow-discrete, overlay 0.2s allow-discrete;
  }

  .language-select::picker(select) {
    inline-size: fit-content;
    min-inline-size: anchor-size(width);
    max-inline-size: min(28rem, calc(100vi - 2rem));
  }

  .language-select:open::picker(select) {
    opacity: 1;
    translate: 0 0;
  }

  @starting-style {
    .language-select:open::picker(select) {
      opacity: 0;
      translate: 0 -0.35rem;
    }
  }

  .language-select option {
    display: flex;
    align-items: center;
    gap: 10px;
    padding-block: 10px;
    padding-inline: 14px;
    border-radius: 12px;
    background: transparent;
    color: #f8fafc;
    transition: background-color 0.2s ease, color 0.2s ease;
  }

  .language-select option:is(:hover, :focus-visible) {
    background: color-mix(in oklch, #8b5cf6 22%, transparent);
  }

  .language-select option:checked {
    background: color-mix(in oklch, #8b5cf6 34%, transparent);
  }

  .language-select option::checkmark {
    content: '✓';
    display: grid;
    place-items: center;
    inline-size: 1.45rem;
    block-size: 1.45rem;
    flex: none;
    order: 2;
    margin-inline-start: 0.35rem;
    border-radius: 999px;
    background: #8b5cf6;
    color: #111827;
    font-weight: 800;
  }

  .language-select .logo {
    display: grid;
    place-items: center;
    inline-size: 34px;
    block-size: 34px;
    border-radius: 0.75rem;
    background: var(--logo-bg);
    color: var(--logo-color);
    font-weight: 900;
    letter-spacing: 0;
  }

  .language-select .logo::before {
    content: attr(data-logo);
    font-size: 0.72em;
  }

  .language-select .language-copy {
    display: grid;
    gap: 0.08rem;
    min-inline-size: max-content;
  }

  .language-select .name {
    font-weight: 800;
    line-height: 1.1;
    white-space: nowrap;
  }

  .language-select .meta {
    font-size: 0.78rem;
    color: color-mix(in oklch, currentColor 70%, transparent);
    line-height: 1.1;
    white-space: nowrap;
  }

  .language-select .meta::before {
    content: attr(data-meta);
  }

  .language-select [data-language="javascript"] .logo {
    --logo-bg: #f7df1e;
    --logo-color: #1f2937;
  }

  .language-select [data-language="typescript"] .logo {
    --logo-bg: #3178c6;
    --logo-color: #f8fafc;
  }

  .language-select [data-language="python"] .logo {
    --logo-bg: #3776ab;
    --logo-color: #fff7d6;
  }

  .language-select [data-language="rust"] .logo {
    --logo-bg: #f97316;
    --logo-color: #111827;
  }

  .language-select [data-language="go"] .logo {
    --logo-bg: #00add8;
    --logo-color: #06202a;
  }
}

@supports not (appearance: base-select) {
  .language-select {
    appearance: none;
    padding-block: 12px;
    padding-inline: 16px calc(16px + 1.75rem);
    border: 1px solid color-mix(in oklch, #8b5cf6 52%, transparent);
    border-radius: 18px;
    background: #111827 url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22%23f8fafc%22%3E%3Cpath%20stroke%3D%22none%22%20d%3D%22M0%200h24v24H0z%22%20fill%3D%22none%22%2F%3E%3Cpath%20d%3D%22M18.707%208.293a1%201%200%200%201%200%201.414l-6%206a1%201%200%200%201-1.414%200l-6-6a1%201%200%200%201%201.414-1.414L12%2013.586l5.293-5.293a1%201%200%200%201%201.414%200%22%2F%3E%3C%2Fsvg%3E") right 0.625rem center / 1.5rem no-repeat;
    color: #f8fafc;
  }
}

Educational guide to customizable select

Customize a select while keeping its native behavior

Learn what base-select enables, how the button and picker connect, and what a form keeps when decoration is unavailable.

Back to the playground

Mental model

A select chooses a value from a closed list. Customizing its presentation does not require rebuilding that interaction in JavaScript.

Anatomy of a customizable selectStatic diagram with the dropdown open. Numbers connect each part to its purpose; try the actual control in the next example.
  1. <button>Surface that opens the dropdown.
  2. <selectedcontent>Copy of the selected option content inside the button.
  3. ::picker-iconSelect opening indicator.
  4. ::picker(select)Surface containing the dropdown list.
  5. <option>Each available choice, with its own value.
  6. ::checkmarkMark for the selected option inside the list.

appearance: none removes some system styling, but does not enable the customizable picker on its own. base-select activates a different presentation for the control and dropdown; apply it to both. The picker becomes a web surface in the top layer, rather than the mobile system interface.

Think of two surfaces: the button shows the current choice and the picker contains the options. ::picker-icon signals opening; ::checkmark marks the selected option. You can style each part without replacing the select with a collection of divs.

Keep a conventional select when text options and the system experience already solve the task. Customization helps when you need to control the surface and present additional content; it does not turn the field into a search box or allow free-form values.

Semantic HTML

Start with a persistent label and understandable options. This example chooses a delivery method and sends no requests.

Delivery method

Open the field and change the option. In a supporting browser, selectedcontent reflects the choice and the picker receives the styles. Without the enhancement, the text options still offer the same values.
Delivery method
<form class="guide-delivery">
  <label for="guide-delivery">Delivery method</label>
  <select id="guide-delivery" name="delivery">
    <button><selectedcontent></selectedcontent></button>
    <option value="standard" selected>Standard · 3–5 days</option>
    <option value="express">Express · 1 day</option>
    <option value="pickup">Store pickup</option>
  </select>
</form>
:root {
  color-scheme: light dark;
}

.guide-delivery {
  display: grid;
  gap: 0.5rem;
  min-inline-size: 0;

  select {
    inline-size: 100%;
    min-inline-size: 0;
    font: inherit;
    padding: 0.75rem;
    color: light-dark(oklch(0.22 0.01 95), oklch(0.95 0.01 95));
    background: light-dark(color-mix(in oklch, oklch(0.95 0.008 95) 94%, white), color-mix(in oklch, oklch(0.22 0.024 260) 92%, black));
    border: 1px solid light-dark(oklch(0.84 0.01 95), oklch(0.36 0.024 260));
    border-radius: 16px;
    corner-shape: squircle;

    &:focus-visible {
      outline: 2px solid light-dark(oklch(0.46 0.14 261), oklch(0.82 0.18 261));
      outline-offset: 3px;
    }
  }
}

@supports (appearance: base-select) {
  .guide-delivery select {
    appearance: base-select;

    &::picker(select) {
      appearance: base-select;
      font: inherit;
      color: light-dark(oklch(0.22 0.01 95), oklch(0.95 0.01 95));
      background: light-dark(color-mix(in oklch, oklch(0.95 0.008 95) 94%, white), color-mix(in oklch, oklch(0.22 0.024 260) 92%, black));
      border: 1px solid light-dark(oklch(0.84 0.01 95), oklch(0.36 0.024 260));
      border-radius: 16px;
      corner-shape: squircle;
      padding: 0.5rem;
      max-inline-size: calc(100vi - 2rem);
    }

    selectedcontent {
      white-space: normal;
      overflow-wrap: anywhere;
    }

    &::picker-icon {
      color: light-dark(oklch(0.46 0.14 261), oklch(0.82 0.18 261));
    }

    &:open {
      border-color: light-dark(oklch(0.46 0.14 261), oklch(0.82 0.18 261));
    }

    option {
      padding: 0.75rem;
      white-space: normal;
      overflow-wrap: anywhere;

      &:hover,
      &:focus-visible {
        outline: 2px solid light-dark(oklch(0.46 0.14 261), oklch(0.82 0.18 261));
        outline-offset: -2px;
      }

      &:checked {
        font-weight: 800;
      }

      &::checkmark {
        color: light-dark(oklch(0.46 0.14 261), oklch(0.82 0.18 261));
      }
    }
  }
}

The label is associated through for/id. name="delivery" identifies the field and each option’s value determines the form data: choosing Express produces delivery=express, rather than the text with the delivery time. Translating the label should not change that contract.

The first child button contains selectedcontent, which the browser fills with a copy of the chosen option’s content. You do not need to synchronize it manually. If you enrich options, keep useful text, avoid IDs that could be duplicated when cloned, and do not place links or interactive controls inside them.

The CSS shows explicit color, radius, and shape values so you can reuse it without BaselineLab styles. light-dark() preserves both themes with color-scheme. The preview uses those same values through site tokens; playground controls do not change the example.

Styles and states

Each part’s selector determines where a rule applies. Focus, opening, and selection are different states.

select::picker(select)

Targets the dropdown, rather than the button. Enable appearance: base-select here too. The browser associates it with the select through an implicit anchor and places it in the top layer; you do not need to add popover to the HTML or fix stacking with z-index.

select::picker-icon

Styles the button’s indicator. Keeping an opening cue helps identify the field; the example changes its color and preserves its native shape.

option:checked / option::checkmark

The first rule describes the selected option; the second, its mark. The example combines text weight with the checkmark so the choice does not depend on color alone. Hover or focus does not mean the value has already changed.

select:open / select:focus-visible

Use :open for presentation while the picker is open and :focus-visible for a noticeable keyboard outline. Do not remove focus when decorating the border. Check options as you navigate them with arrow keys too.

The recipe needs no animation. If you add entry and exit transitions, verify @starting-style, discrete transitions, and overlay separately, and respect prefers-reduced-motion. Picker support does not certify support for that animated recipe.

Support and compatibility

The enhancement should preserve a useful choice even when the browser does not render all the modern parts.

Check the base-select value of appearance and the tables for selectedcontent, ::picker(select), ::picker-icon, and ::checkmark separately. The overall status of appearance as a property does not make all its values interoperable.

@supports (appearance: base-select) limits enhancement styles to browsers that accept that value. It is a syntax query, not a test of opening, cloning, or accessibility. Check the complete behavior in your target browsers. The base preserves the conventional appearance and readable text in every option.

Explicit conventional reference

This second field uses conventional HTML and does not enable base-select. It lets you compare both experiences in your browser; it does not demonstrate how a non-supporting engine renders the first recipe.
Explicit conventional reference
<form class="guide-delivery-classic">
  <label for="guide-delivery-classic">Delivery method</label>
  <select id="guide-delivery-classic" name="delivery">
    <option value="standard" selected>Standard · 3–5 days</option>
    <option value="express">Express · 1 day</option>
    <option value="pickup">Store pickup</option>
  </select>
</form>
:root {
  color-scheme: light dark;
}

.guide-delivery-classic {
  display: grid;
  gap: 0.5rem;
  min-inline-size: 0;

  select {
    inline-size: 100%;
    min-inline-size: 0;
    font: inherit;
    padding: 0.75rem;
    color: light-dark(oklch(0.22 0.01 95), oklch(0.95 0.01 95));
    background: light-dark(color-mix(in oklch, oklch(0.95 0.008 95) 94%, white), color-mix(in oklch, oklch(0.22 0.024 260) 92%, black));
    border: 1px solid light-dark(oklch(0.84 0.01 95), oklch(0.36 0.024 260));
    border-radius: 16px;
    corner-shape: squircle;

    &:focus-visible {
      outline: 2px solid light-dark(oklch(0.46 0.14 261), oklch(0.82 0.18 261));
      outline-offset: 3px;
    }
  }
}

Common mistakes

Diagnose the part and state before adding more rules or replacing the control.

The picker ignores styles

Expected result
The button and list share the customized presentation.
Cause
base-select was only enabled on the select, or the browser does not implement the part being used.
Solution
Enable it on ::picker(select) too; check its support and test actual opening and selection. Do not infer complete support from CSS.supports().

The selected content loses information

Expected result
The choice is understandable in both the button and list.
Cause
Information depends on decoration or rich content that is not preserved in the conventional presentation.
Solution
Include a readable name in every option. Use a stable value and selectedcontent for presentation; do not use decorative text as form data.

A long option overflows

Expected result
Text remains readable on a narrow screen.
Cause
base-select no longer sizes the control according to the longest option. An intrinsic width or nowrap can force overflow.
Solution
Give the field an adaptive width, allow text wrapping, and constrain the picker to the viewport. Test all choices and enlarged text, rather than only the first.

The control looks good but loses focus

Expected result
It can be opened, navigated, selected, and closed with a keyboard.
Cause
outline was removed or added logic interferes with native behavior.
Solution
Keep visible focus. Test arrows, selection, Escape, and returning to the field; review names and announcements with assistive technologies in your target environments.