Open demo

CSS code

HTML
<div><span class="lbl">Icons, descriptions and prices</span><div class="card">
  <div class="cs-field">
    <label class="cs-label" for="cs-ship">Delivery</label>
    <select class="cs" id="cs-ship" name="delivery" aria-describedby="cs-ship-hint">
      <button><selectedcontent></selectedcontent></button>
      <option value="standard"><span class="cs-ico" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21 8-9-5-9 5v8l9 5 9-5V8Z"/><path d="m3 8 9 5 9-5M12 13v8"/></svg></span><span class="cs-text"><span>Standard</span><span class="cs-sep"> — </span><span class="cs-desc">3 to 5 working days</span></span><span class="cs-price"><span class="cs-sep">, </span>Free</span></option>
      <option value="express" selected><span class="cs-ico" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2 4 14h7l-1 8 9-12h-7l1-8Z"/></svg></span><span class="cs-text"><span>Express</span><span class="cs-sep"> — </span><span class="cs-desc">Next working day</span></span><span class="cs-price"><span class="cs-sep">, </span>€6.90</span></option>
      <option value="sameday"><span class="cs-ico" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg></span><span class="cs-text"><span>Same day</span><span class="cs-sep"> — </span><span class="cs-desc">Order before 14:00, arrives by 21:00</span></span><span class="cs-price"><span class="cs-sep">, </span>€12.50</span></option>
      <option value="pickup"><span class="cs-ico" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 21s-7-6.2-7-11.5a7 7 0 0 1 14 0C19 14.8 12 21 12 21Z"/><circle cx="12" cy="9.5" r="2.5"/></svg></span><span class="cs-text"><span>Pickup point</span><span class="cs-sep"> — </span><span class="cs-desc">Collect in 2 days from 340 lockers</span></span><span class="cs-price"><span class="cs-sep">, </span>Free</span></option>
    </select>
    <p class="cs-hint" id="cs-ship-hint">Prices include VAT. Tracking arrives by email.</p>
  </div>
</div></div>

<div><span class="lbl">Colour dots and typeface previews</span><div class="card">
  <div class="cs-row">
    <div class="cs-field">
      <label class="cs-label" for="cs-status">Status</label>
      <select class="cs" id="cs-status" name="status">
        <button><selectedcontent></selectedcontent></button>
        <option value="draft"><span class="cs-dot" style="--dot:#78716c" aria-hidden="true"></span>Draft</option>
        <option value="review"><span class="cs-dot" style="--dot:#d97706" aria-hidden="true"></span>In review</option>
        <option value="scheduled" selected><span class="cs-dot" style="--dot:#2563eb" aria-hidden="true"></span>Scheduled</option>
        <option value="published"><span class="cs-dot" style="--dot:#16a34a" aria-hidden="true"></span>Published</option>
        <option value="archived"><span class="cs-dot" style="--dot:#be123c" aria-hidden="true"></span>Archived</option>
      </select>
    </div>
    <div class="cs-field">
      <label class="cs-label" for="cs-font">Heading typeface</label>
      <select class="cs" id="cs-font" name="heading_font">
        <button><selectedcontent></selectedcontent></button>
        <option value="serif"><span class="cs-text"><span class="cs-font ff-serif">Transitional serif</span><span class="cs-sep"> — </span><span class="cs-desc">Charter, Cambria</span></span></option>
        <option value="geometric" selected><span class="cs-text"><span class="cs-font ff-geo">Geometric sans</span><span class="cs-sep"> — </span><span class="cs-desc">Avenir, Montserrat</span></span></option>
        <option value="rounded"><span class="cs-text"><span class="cs-font ff-round">Rounded sans</span><span class="cs-sep"> — </span><span class="cs-desc">SF Rounded, Quicksand</span></span></option>
        <option value="didone"><span class="cs-text"><span class="cs-font ff-didone">Didone</span><span class="cs-sep"> — </span><span class="cs-desc">Didot, Bodoni</span></span></option>
        <option value="mono"><span class="cs-text"><span class="cs-font ff-mono">Monospace</span><span class="cs-sep"> — </span><span class="cs-desc">Menlo, Cascadia Code</span></span></option>
      </select>
    </div>
  </div>
</div></div>
CSS
/* Customizable select: a real <select> with rich options. Where appearance: base-select is supported (Chrome and Edge
   135+) the button, the picker and every option are styled, and <selectedcontent> copies the picked option into the
   button. Other browsers ignore the extra markup and show a styled native select with the same option text. */
.cs-field{display:grid;gap:7px;min-width:0}
.cs-label{font-size:.9rem;font-weight:600;color:#2a1a1f}
.cs-hint{font-size:.82rem;color:#6b5a60}
.cs{--cs-accent:#be123c;--cs-tint:#fdeef1;--cs-ring:rgba(190,18,60,.22);--cs-line:#948a8d;--cs-ink:#2a1a1f;--cs-muted:#6b5a60;
  --cs-chev:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%236b5a60' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4 6 4 4 4-4'/%3E%3C/svg%3E");
  -webkit-appearance:none;appearance:none;display:block;width:100%;height:48px;margin:0;padding:0 42px 0 14px;font:inherit;font-size:.95rem;
  color:var(--cs-ink);color-scheme:light;cursor:pointer;background:#fff var(--cs-chev) no-repeat right 14px center/16px;
  border:1px solid var(--cs-line);border-radius:12px;box-shadow:0 1px 2px rgba(42,26,31,.06);transition:border-color .15s,box-shadow .15s}
.cs:hover{border-color:#716669}
.cs:focus-visible{outline:none;border-color:var(--cs-accent);box-shadow:0 0 0 4px var(--cs-ring)}
.cs-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:16px}
.cs-ico{display:grid;place-items:center;flex:none;width:32px;height:32px;border-radius:9px;background:var(--cs-tint);color:var(--cs-accent)}
.cs-ico svg{width:18px;height:18px}
.cs-dot{flex:none;width:10px;height:10px;border-radius:50%;background:var(--dot)}
.ff-serif{font-family:Charter,"Bitstream Charter","Sitka Text",Cambria,serif}
.ff-geo{font-family:Avenir,Montserrat,Corbel,"URW Gothic",source-sans-pro,sans-serif}
.ff-round{font-family:ui-rounded,"Hiragino Maru Gothic ProN",Quicksand,Comfortaa,Manjari,"Arial Rounded MT","Arial Rounded MT Bold",Calibri,source-sans-pro,sans-serif}
.ff-didone{font-family:Didot,"Bodoni MT","Noto Serif Display","URW Palladio L",P052,Sylfaen,serif}
.ff-mono{font-family:ui-monospace,"Cascadia Code","Source Code Pro",Menlo,Consolas,"DejaVu Sans Mono",monospace}
@supports (appearance: base-select) {
  .cs,.cs::picker(select){appearance:base-select}
  .cs{display:flex;align-items:center;gap:10px;height:auto;min-height:48px;padding:6px 14px 6px 8px;background-image:none}
  .cs:not(:has(.cs-ico)){padding-left:14px}
  .cs:open{border-color:var(--cs-accent);box-shadow:0 0 0 4px var(--cs-ring)}
  .cs::picker-icon{content:"";width:16px;height:16px;background:var(--cs-chev) center/16px no-repeat;transition:rotate .2s}
  .cs:open::picker-icon{rotate:180deg}
  .cs>button{display:flex;flex:1;min-width:0}
  .cs selectedcontent{display:flex;align-items:center;gap:10px;min-width:0;font-weight:600}
  .cs selectedcontent .cs-desc,.cs selectedcontent .cs-price,.cs .cs-sep{display:none}
  .cs::picker(select){margin-top:6px;padding:6px;background:#fff;border:1px solid #e6d9dc;border-radius:14px;box-shadow:0 18px 40px -12px rgba(42,26,31,.3);
    transition:opacity .15s,translate .15s,display .15s allow-discrete,overlay .15s allow-discrete}
  .cs:not(:open)::picker(select){opacity:0;translate:0 -4px}
  @starting-style{.cs:open::picker(select){opacity:0;translate:0 -4px}}
  .cs option{display:flex;align-items:center;gap:12px;min-width:0;padding:8px 10px;border-radius:9px;font-size:.93rem;cursor:pointer;outline:none}
  .cs option:hover,.cs option:focus-visible{background:var(--cs-tint)}
  .cs option:focus-visible{box-shadow:inset 0 0 0 2px var(--cs-accent)}
  .cs option:checked{font-weight:600}
  .cs option::checkmark{order:9;padding-left:10px;color:var(--cs-accent);font-weight:700}
  .cs option:not(:has(.cs-price))::checkmark{margin-left:auto}
  .cs-text{display:grid;min-width:0}
  .cs-desc{font-size:.8rem;font-weight:400;color:var(--cs-muted)}
  .cs-price{margin-left:auto;font-size:.85rem;font-weight:600;font-variant-numeric:tabular-nums}
  .cs-font{font-size:1.05rem}
}
@media (prefers-reduced-motion:reduce){.cs,.cs::picker(select),.cs::picker-icon{transition:none}}

Bootstrap 5 code

Requires: Bootstrap 5.3.8 CSS

HTML
<div><span class="lbl">Icons, descriptions and prices</span><div class="card demo-card"><div class="card-body">
  <div class="cs-field">
    <label class="form-label" for="cs-ship">Delivery</label>
    <select class="form-select cs" id="cs-ship" name="delivery" aria-describedby="cs-ship-hint">
      <button><selectedcontent></selectedcontent></button>
      <option value="standard"><span class="cs-ico" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21 8-9-5-9 5v8l9 5 9-5V8Z"/><path d="m3 8 9 5 9-5M12 13v8"/></svg></span><span class="cs-text"><span>Standard</span><span class="cs-sep"> — </span><span class="cs-desc">3 to 5 working days</span></span><span class="cs-price"><span class="cs-sep">, </span>Free</span></option>
      <option value="express" selected><span class="cs-ico" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2 4 14h7l-1 8 9-12h-7l1-8Z"/></svg></span><span class="cs-text"><span>Express</span><span class="cs-sep"> — </span><span class="cs-desc">Next working day</span></span><span class="cs-price"><span class="cs-sep">, </span>€6.90</span></option>
      <option value="sameday"><span class="cs-ico" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg></span><span class="cs-text"><span>Same day</span><span class="cs-sep"> — </span><span class="cs-desc">Order before 14:00, arrives by 21:00</span></span><span class="cs-price"><span class="cs-sep">, </span>€12.50</span></option>
      <option value="pickup"><span class="cs-ico" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 21s-7-6.2-7-11.5a7 7 0 0 1 14 0C19 14.8 12 21 12 21Z"/><circle cx="12" cy="9.5" r="2.5"/></svg></span><span class="cs-text"><span>Pickup point</span><span class="cs-sep"> — </span><span class="cs-desc">Collect in 2 days from 340 lockers</span></span><span class="cs-price"><span class="cs-sep">, </span>Free</span></option>
    </select>
    <p class="form-text" id="cs-ship-hint">Prices include VAT. Tracking arrives by email.</p>
  </div>
</div></div></div>

<div><span class="lbl">Colour dots and typeface previews</span><div class="card demo-card"><div class="card-body">
  <div class="row g-3">
    <div class="col-sm-6 cs-field">
      <label class="form-label" for="cs-status">Status</label>
      <select class="form-select cs" id="cs-status" name="status">
        <button><selectedcontent></selectedcontent></button>
        <option value="draft"><span class="cs-dot" style="--dot:#78716c" aria-hidden="true"></span>Draft</option>
        <option value="review"><span class="cs-dot" style="--dot:#d97706" aria-hidden="true"></span>In review</option>
        <option value="scheduled" selected><span class="cs-dot" style="--dot:#2563eb" aria-hidden="true"></span>Scheduled</option>
        <option value="published"><span class="cs-dot" style="--dot:#16a34a" aria-hidden="true"></span>Published</option>
        <option value="archived"><span class="cs-dot" style="--dot:#be123c" aria-hidden="true"></span>Archived</option>
      </select>
    </div>
    <div class="col-sm-6 cs-field">
      <label class="form-label" for="cs-font">Heading typeface</label>
      <select class="form-select cs" id="cs-font" name="heading_font">
        <button><selectedcontent></selectedcontent></button>
        <option value="serif"><span class="cs-text"><span class="cs-font ff-serif">Transitional serif</span><span class="cs-sep"> — </span><span class="cs-desc">Charter, Cambria</span></span></option>
        <option value="geometric" selected><span class="cs-text"><span class="cs-font ff-geo">Geometric sans</span><span class="cs-sep"> — </span><span class="cs-desc">Avenir, Montserrat</span></span></option>
        <option value="rounded"><span class="cs-text"><span class="cs-font ff-round">Rounded sans</span><span class="cs-sep"> — </span><span class="cs-desc">SF Rounded, Quicksand</span></span></option>
        <option value="didone"><span class="cs-text"><span class="cs-font ff-didone">Didone</span><span class="cs-sep"> — </span><span class="cs-desc">Didot, Bodoni</span></span></option>
        <option value="mono"><span class="cs-text"><span class="cs-font ff-mono">Monospace</span><span class="cs-sep"> — </span><span class="cs-desc">Menlo, Cascadia Code</span></span></option>
      </select>
    </div>
  </div>
</div></div></div>
CSS
/* Customizable select on Bootstrap's .form-select. Where appearance: base-select is supported (Chrome and Edge 135+)
   the button, picker and options are styled and <selectedcontent> copies the picked option into the button. Other
   browsers ignore the extra markup and show .form-select with the same option text. */
.cs-field{display:grid;gap:7px;min-width:0}
.cs-field .form-label{margin:0;font-size:.9rem;font-weight:600;color:#2a1a1f}
.cs-field .form-text{margin:0;font-size:.82rem;color:#6b5a60}
.form-select.cs{--cs-accent:#be123c;--cs-tint:#fdeef1;--cs-ring:rgba(190,18,60,.22);--cs-line:#948a8d;--cs-ink:#2a1a1f;--cs-muted:#6b5a60;
  --cs-chev:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%236b5a60' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4 6 4 4 4-4'/%3E%3C/svg%3E");
  --bs-form-select-bg-img:var(--cs-chev);height:48px;padding:0 42px 0 14px;font-size:.95rem;line-height:1.45;color:var(--cs-ink);color-scheme:light;
  cursor:pointer;background-position:right 14px center;background-size:16px;border-color:var(--cs-line);border-radius:12px;box-shadow:0 1px 2px rgba(42,26,31,.06)}
.form-select.cs:hover{border-color:#716669}
.form-select.cs:focus{border-color:var(--cs-line);box-shadow:0 1px 2px rgba(42,26,31,.06)}
.form-select.cs:focus-visible{border-color:var(--cs-accent);box-shadow:0 0 0 4px var(--cs-ring)}
.cs-ico{display:grid;place-items:center;flex:none;width:32px;height:32px;border-radius:9px;background:#fdeef1;color:#be123c}
.cs-ico svg{width:18px;height:18px}
.cs-dot{flex:none;width:10px;height:10px;border-radius:50%;background:var(--dot)}
.ff-serif{font-family:Charter,"Bitstream Charter","Sitka Text",Cambria,serif}
.ff-geo{font-family:Avenir,Montserrat,Corbel,"URW Gothic",source-sans-pro,sans-serif}
.ff-round{font-family:ui-rounded,"Hiragino Maru Gothic ProN",Quicksand,Comfortaa,Manjari,"Arial Rounded MT","Arial Rounded MT Bold",Calibri,source-sans-pro,sans-serif}
.ff-didone{font-family:Didot,"Bodoni MT","Noto Serif Display","URW Palladio L",P052,Sylfaen,serif}
.ff-mono{font-family:ui-monospace,"Cascadia Code","Source Code Pro",Menlo,Consolas,"DejaVu Sans Mono",monospace}
@supports (appearance: base-select) {
  .form-select.cs,.form-select.cs::picker(select){appearance:base-select}
  .form-select.cs{display:flex;align-items:center;gap:10px;height:auto;min-height:48px;padding:6px 14px 6px 8px;background-image:none}
  .form-select.cs:not(:has(.cs-ico)){padding-left:14px}
  .form-select.cs:open{border-color:var(--cs-accent);box-shadow:0 0 0 4px var(--cs-ring)}
  .form-select.cs::picker-icon{content:"";width:16px;height:16px;background:var(--cs-chev) center/16px no-repeat;transition:rotate .2s}
  .form-select.cs:open::picker-icon{rotate:180deg}
  .form-select.cs>button{display:flex;flex:1;min-width:0}
  .form-select.cs selectedcontent{display:flex;align-items:center;gap:10px;min-width:0;font-weight:600}
  .form-select.cs selectedcontent .cs-desc,.form-select.cs selectedcontent .cs-price,.form-select.cs .cs-sep{display:none}
  .form-select.cs::picker(select){margin-top:6px;padding:6px;background:#fff;border:1px solid #e6d9dc;border-radius:14px;box-shadow:0 18px 40px -12px rgba(42,26,31,.3);
    transition:opacity .15s,translate .15s,display .15s allow-discrete,overlay .15s allow-discrete}
  .form-select.cs:not(:open)::picker(select){opacity:0;translate:0 -4px}
  @starting-style{.form-select.cs:open::picker(select){opacity:0;translate:0 -4px}}
  .form-select.cs option{display:flex;align-items:center;gap:12px;min-width:0;padding:8px 10px;border-radius:9px;font-size:.93rem;cursor:pointer;outline:none}
  .form-select.cs option:hover,.form-select.cs option:focus-visible{background:var(--cs-tint)}
  .form-select.cs option:focus-visible{box-shadow:inset 0 0 0 2px var(--cs-accent)}
  .form-select.cs option:checked{font-weight:600}
  .form-select.cs option::checkmark{order:9;padding-left:10px;color:var(--cs-accent);font-weight:700}
  .form-select.cs option:not(:has(.cs-price))::checkmark{margin-left:auto}
  .cs-text{display:grid;min-width:0}
  .cs-desc{font-size:.8rem;font-weight:400;color:var(--cs-muted)}
  .cs-price{margin-left:auto;font-size:.85rem;font-weight:600;font-variant-numeric:tabular-nums}
  .cs-font{font-size:1.05rem}
}
@media (prefers-reduced-motion:reduce){.form-select.cs,.form-select.cs::picker(select),.form-select.cs::picker-icon{transition:none}}

Tailwind 4 code

Requires: Tailwind CSS 4

HTML
<div><span class="mb-3 block text-[.72rem] tracking-[.12em] text-[#6b5a60] uppercase">Icons, descriptions and prices</span><div class="rounded-2xl border border-[#efe3e6] bg-white px-6 pt-[22px] pb-6 shadow-[0_1px_2px_rgba(42,26,31,.04)]">
  <div class="grid min-w-0 gap-[7px]">
    <label class="text-[.9rem] font-semibold" for="cs-ship">Delivery</label>
    <select class="cs block h-12 w-full cursor-pointer appearance-none rounded-xl border border-cs-line bg-white bg-(image:--cs-chev) bg-size-[16px] bg-position-[right_14px_center] bg-no-repeat pr-[42px] pl-3.5 text-[.95rem] text-cs-ink shadow-[0_1px_2px_rgba(42,26,31,.06)] [color-scheme:light] transition-[border-color,box-shadow] duration-150 hover:border-[#716669] focus-visible:border-cs-accent focus-visible:shadow-[0_0_0_4px_rgba(190,18,60,.22)] focus-visible:outline-none motion-reduce:transition-none" id="cs-ship" name="delivery" aria-describedby="cs-ship-hint">
      <button><selectedcontent></selectedcontent></button>
      <option value="standard"><span class="grid size-8 flex-none place-items-center rounded-[9px] bg-cs-tint text-cs-accent [&_svg]:size-[18px]" data-pic aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21 8-9-5-9 5v8l9 5 9-5V8Z"/><path d="m3 8 9 5 9-5M12 13v8"/></svg></span><span class="grid min-w-0"><span>Standard</span><span class="hidden"> — </span><span class="text-[.8rem] font-normal text-cs-muted in-[selectedcontent]:hidden">3 to 5 working days</span></span><span class="ml-auto text-[.85rem] font-semibold tabular-nums in-[selectedcontent]:hidden"><span class="hidden">, </span>Free</span></option>
      <option value="express" selected><span class="grid size-8 flex-none place-items-center rounded-[9px] bg-cs-tint text-cs-accent [&_svg]:size-[18px]" data-pic aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2 4 14h7l-1 8 9-12h-7l1-8Z"/></svg></span><span class="grid min-w-0"><span>Express</span><span class="hidden"> — </span><span class="text-[.8rem] font-normal text-cs-muted in-[selectedcontent]:hidden">Next working day</span></span><span class="ml-auto text-[.85rem] font-semibold tabular-nums in-[selectedcontent]:hidden"><span class="hidden">, </span>€6.90</span></option>
      <option value="sameday"><span class="grid size-8 flex-none place-items-center rounded-[9px] bg-cs-tint text-cs-accent [&_svg]:size-[18px]" data-pic aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg></span><span class="grid min-w-0"><span>Same day</span><span class="hidden"> — </span><span class="text-[.8rem] font-normal text-cs-muted in-[selectedcontent]:hidden">Order before 14:00, arrives by 21:00</span></span><span class="ml-auto text-[.85rem] font-semibold tabular-nums in-[selectedcontent]:hidden"><span class="hidden">, </span>€12.50</span></option>
      <option value="pickup"><span class="grid size-8 flex-none place-items-center rounded-[9px] bg-cs-tint text-cs-accent [&_svg]:size-[18px]" data-pic aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 21s-7-6.2-7-11.5a7 7 0 0 1 14 0C19 14.8 12 21 12 21Z"/><circle cx="12" cy="9.5" r="2.5"/></svg></span><span class="grid min-w-0"><span>Pickup point</span><span class="hidden"> — </span><span class="text-[.8rem] font-normal text-cs-muted in-[selectedcontent]:hidden">Collect in 2 days from 340 lockers</span></span><span class="ml-auto text-[.85rem] font-semibold tabular-nums in-[selectedcontent]:hidden"><span class="hidden">, </span>Free</span></option>
    </select>
    <p class="text-[.82rem] text-cs-muted" id="cs-ship-hint">Prices include VAT. Tracking arrives by email.</p>
  </div>
</div></div>

<div><span class="mb-3 block text-[.72rem] tracking-[.12em] text-[#6b5a60] uppercase">Colour dots and typeface previews</span><div class="rounded-2xl border border-[#efe3e6] bg-white px-6 pt-[22px] pb-6 shadow-[0_1px_2px_rgba(42,26,31,.04)]">
  <div class="grid grid-cols-[repeat(auto-fit,minmax(220px,1fr))] gap-4">
    <div class="grid min-w-0 gap-[7px]">
      <label class="text-[.9rem] font-semibold" for="cs-status">Status</label>
      <select class="cs block h-12 w-full cursor-pointer appearance-none rounded-xl border border-cs-line bg-white bg-(image:--cs-chev) bg-size-[16px] bg-position-[right_14px_center] bg-no-repeat pr-[42px] pl-3.5 text-[.95rem] text-cs-ink shadow-[0_1px_2px_rgba(42,26,31,.06)] [color-scheme:light] transition-[border-color,box-shadow] duration-150 hover:border-[#716669] focus-visible:border-cs-accent focus-visible:shadow-[0_0_0_4px_rgba(190,18,60,.22)] focus-visible:outline-none motion-reduce:transition-none" id="cs-status" name="status">
        <button><selectedcontent></selectedcontent></button>
        <option value="draft"><span class="size-2.5 flex-none rounded-full bg-(--dot)" style="--dot:#78716c" aria-hidden="true"></span>Draft</option>
        <option value="review"><span class="size-2.5 flex-none rounded-full bg-(--dot)" style="--dot:#d97706" aria-hidden="true"></span>In review</option>
        <option value="scheduled" selected><span class="size-2.5 flex-none rounded-full bg-(--dot)" style="--dot:#2563eb" aria-hidden="true"></span>Scheduled</option>
        <option value="published"><span class="size-2.5 flex-none rounded-full bg-(--dot)" style="--dot:#16a34a" aria-hidden="true"></span>Published</option>
        <option value="archived"><span class="size-2.5 flex-none rounded-full bg-(--dot)" style="--dot:#be123c" aria-hidden="true"></span>Archived</option>
      </select>
    </div>
    <div class="grid min-w-0 gap-[7px]">
      <label class="text-[.9rem] font-semibold" for="cs-font">Heading typeface</label>
      <select class="cs block h-12 w-full cursor-pointer appearance-none rounded-xl border border-cs-line bg-white bg-(image:--cs-chev) bg-size-[16px] bg-position-[right_14px_center] bg-no-repeat pr-[42px] pl-3.5 text-[.95rem] text-cs-ink shadow-[0_1px_2px_rgba(42,26,31,.06)] [color-scheme:light] transition-[border-color,box-shadow] duration-150 hover:border-[#716669] focus-visible:border-cs-accent focus-visible:shadow-[0_0_0_4px_rgba(190,18,60,.22)] focus-visible:outline-none motion-reduce:transition-none" id="cs-font" name="heading_font">
        <button><selectedcontent></selectedcontent></button>
        <option value="serif"><span class="grid min-w-0"><span class="text-[1.05rem] font-[Charter,'Bitstream_Charter','Sitka_Text',Cambria,serif]">Transitional serif</span><span class="hidden"> — </span><span class="text-[.8rem] font-normal text-cs-muted in-[selectedcontent]:hidden">Charter, Cambria</span></span></option>
        <option value="geometric" selected><span class="grid min-w-0"><span class="text-[1.05rem] font-[Avenir,Montserrat,Corbel,'URW_Gothic',source-sans-pro,sans-serif]">Geometric sans</span><span class="hidden"> — </span><span class="text-[.8rem] font-normal text-cs-muted in-[selectedcontent]:hidden">Avenir, Montserrat</span></span></option>
        <option value="rounded"><span class="grid min-w-0"><span class="text-[1.05rem] font-[ui-rounded,'Hiragino_Maru_Gothic_ProN',Quicksand,Comfortaa,Manjari,'Arial_Rounded_MT','Arial_Rounded_MT_Bold',Calibri,source-sans-pro,sans-serif]">Rounded sans</span><span class="hidden"> — </span><span class="text-[.8rem] font-normal text-cs-muted in-[selectedcontent]:hidden">SF Rounded, Quicksand</span></span></option>
        <option value="didone"><span class="grid min-w-0"><span class="text-[1.05rem] font-[Didot,'Bodoni_MT','Noto_Serif_Display','URW_Palladio_L',P052,Sylfaen,serif]">Didone</span><span class="hidden"> — </span><span class="text-[.8rem] font-normal text-cs-muted in-[selectedcontent]:hidden">Didot, Bodoni</span></span></option>
        <option value="mono"><span class="grid min-w-0"><span class="text-[1.05rem] font-[ui-monospace,'Cascadia_Code','Source_Code_Pro',Menlo,Consolas,'DejaVu_Sans_Mono',monospace]">Monospace</span><span class="hidden"> — </span><span class="text-[.8rem] font-normal text-cs-muted in-[selectedcontent]:hidden">Menlo, Cascadia Code</span></span></option>
      </select>
    </div>
  </div>
</div></div>
CSS
@theme {
  --color-cs-accent: #be123c;
  --color-cs-tint: #fdeef1;
  --color-cs-line: #948a8d;
  --color-cs-ink: #2a1a1f;
  --color-cs-muted: #6b5a60;
}
:root { --cs-chev: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%236b5a60' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4 6 4 4 4-4'/%3E%3C/svg%3E"); }
/* The utilities in the markup draw the native select. Where appearance: base-select is supported (Chrome and Edge 135+),
   this block switches .cs to the customizable select and styles the parts utilities cannot reach: ::picker(select),
   ::picker-icon, ::checkmark and <selectedcontent>. */
@supports (appearance: base-select) {
  .cs, .cs::picker(select) { appearance: base-select; }
  .cs { display: flex; align-items: center; gap: 10px; height: auto; min-height: 48px; padding: 6px 14px 6px 8px; background-image: none; }
  .cs:not(:has([data-pic])) { padding-left: 14px; }
  .cs:open { border-color: var(--color-cs-accent); box-shadow: 0 0 0 4px rgb(190 18 60 / .22); }
  .cs::picker-icon { content: ""; width: 16px; height: 16px; background: var(--cs-chev) center / 16px no-repeat; transition: rotate .2s; }
  .cs:open::picker-icon { rotate: 180deg; }
  .cs > button { display: flex; flex: 1; min-width: 0; }
  .cs selectedcontent { display: flex; align-items: center; gap: 10px; min-width: 0; font-weight: 600; }
  .cs::picker(select) { margin-top: 6px; padding: 6px; background: #fff; border: 1px solid #e6d9dc; border-radius: 14px; box-shadow: 0 18px 40px -12px rgb(42 26 31 / .3);
    transition: opacity .15s, translate .15s, display .15s allow-discrete, overlay .15s allow-discrete; }
  .cs:not(:open)::picker(select) { opacity: 0; translate: 0 -4px; }
  @starting-style { .cs:open::picker(select) { opacity: 0; translate: 0 -4px; } }
  .cs option { display: flex; align-items: center; gap: 12px; min-width: 0; padding: 8px 10px; border-radius: 9px; font-size: .93rem; cursor: pointer; outline: none; }
  .cs option:hover, .cs option:focus-visible { background: var(--color-cs-tint); }
  .cs option:focus-visible { box-shadow: inset 0 0 0 2px var(--color-cs-accent); }
  .cs option:checked { font-weight: 600; }
  .cs option::checkmark { order: 9; padding-left: 10px; color: var(--color-cs-accent); font-weight: 700; }
  .cs option:not(:has(.ml-auto))::checkmark { margin-left: auto; }
}
@media (prefers-reduced-motion: reduce) { .cs, .cs::picker(select), .cs::picker-icon { transition: none; } }

About this set

Rich dropdowns that are still a plain select element, built on the new customizable select. Icons, descriptions and prices is a delivery picker whose options show an icon tile, a name, a line of detail and a price, while the closed button shows only the icon and name. Colour dots and typeface previews pairs a status select with coloured dots and a heading typeface select that draws every option in its own font. Where appearance: base-select is supported, the CSS styles the button, the ::picker(select) popup, ::picker-icon and ::checkmark, and the selectedcontent element copies the chosen option into the button. The picker fades in with @starting-style, which is switched off under reduced motion. Other browsers skip the extra markup and render the same options as text in a styled native select, so the separators in the markup read as Express — Next working day, €6.90. Because it is a real select, keyboard support, form submission, validation and mobile pickers need no JavaScript at all.

What’s included

  • appearance: base-select with a styled ::picker(select)
  • selectedcontent shows the picked icon or dot in the button
  • Options with icons, descriptions, prices, dots and typefaces
  • Clean text fallback in browsers without customizable select
  • No JavaScript

Accessibility

Each select has a visible label, and keyboard, screen reader and form behaviour are the browser's own because nothing replaces the select element. Icons and dots are aria-hidden, focus shows a ring on the button and an inset ring on the focused option, and the picker animation and chevron turn stop under prefers-reduced-motion.

Customise it

Change --cs-accent, --cs-tint and --cs-line on .cs, and the stroke colour inside --cs-chev. In Bootstrap the same variables sit on .form-select.cs; in Tailwind edit the --color-cs-* theme colours, with the base-select rules in the style block.