0

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.

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;
  }
}