Stile di selezione con brand

Funzionalità web: <select> personalizzabile

L'API select personalizzabile offre un modo dichiarativo basato su CSS per applicare uno stile agli elementi <select> in modo che corrispondano perfettamente al sistema di progettazione del tuo brand. Se attivi appearance: base-select, ottieni l'accesso al DOM shadow interno dell'elemento select, che ti consente di applicare uno stile al pulsante, all'elenco del selettore di opzioni, all'icona a forma di freccia e all'indicatore di segno di spunta utilizzando le proprietà CSS standard.

In precedenza, per ottenere un elemento select completamente personalizzato con il brand, era necessario ricostruire il controllo da zero con JavaScript, il che spesso interrompeva l'accessibilità, la navigazione da tastiera e l'integrazione dei moduli nativi. Con appearance: base-select, ottieni un aspetto personalizzato mentre il browser gestisce la gestione dello stato attivo, il rendering del livello superiore e le associazioni di accessibilità.

Modalità di implementazione

Per implementare lo stile di selezione con branding:

  1. Attiva la personalizzazione: applica appearance: base-select sia all'elemento <select> sia allo pseudo-elemento ::picker(select) (che ha come target l'elenco a discesa delle opzioni).
  2. (Facoltativo) Struttura il pulsante personalizzato: definisci un elemento <button> direttamente all'interno di <select> per sostituire l'attivatore predefinito. Utilizza l'elemento <selectedcontent> all'interno di questo pulsante per rappresentare il testo o i contenuti dell'opzione attualmente selezionata.
  3. Definisci lo stile dell'elenco del selettore: utilizza lo pseudo-elemento ::picker(select) per applicare tipografia, colori di sfondo, bordi e ombre all'elenco a discesa. Il browser esegue il rendering di questo elemento nel livello superiore, rendendo i conflitti di z-index un ricordo del passato.
  4. Icone interne di stile:
    • Utilizza select::picker-icon per applicare uno stile all'icona a forma di freccia o sostituirla.
    • Utilizza option::checkmark per applicare uno stile all'indicatore del segno di spunta accanto all'opzione attiva.
  5. Opzioni di stile: applica stili agli elementi <option> per gli stati di passaggio del mouse, il padding e il layout.

Codice di esempio: Branded Courier Select

L'esempio seguente mostra un menu di selezione personalizzato con uno stile con un carattere monospace e bordi tratteggiati per corrispondere a un'estetica specifica del brand "parcel".

/* Enable customization for the select and its picker */
.brand-select,
.brand-select::picker(select) {
  appearance: base-select;
}

/* Style the visible trigger button */
.brand-select {
  font-family: 'Courier New', monospace;
  background-color: #fffaf0;
  color: #8b4513;
  border: 2px dashed #8b4513;
  border-radius: 4px;
  padding: 0.75rem;
  font-size: 1rem;
  cursor: pointer;
}

/* Style the dropdown options list */
.brand-select::picker(select) {
  font-family: 'Courier New', monospace;
  background-color: #fffaf0;
  border: 2px dashed #8b4513;
  border-radius: 4px;
  padding: 0.5rem;
}

/* Customize internal part colors to match text */
.brand-select::picker-icon {
  color: #8b4513;
}

.brand-select option::checkmark {
  color: #8b4513;
}

/* Style individual options and hover effects */
.brand-select option {
  padding: 0.5rem;
  border-radius: 4px;
  color: #8b4513;
  cursor: pointer;
}

.brand-select option:hover {
  background-color: #fdf5e6;
}
<label for="preferences">Select shipping preference</label>
<select class="brand-select" id="preferences" name="preferences">
  <button>
    <selectedcontent></selectedcontent>
  </button>
  <option value="standard">Standard Shipping</option>
  <option value="express" selected>Express Shipping</option>
  <option value="overnight">Overnight Delivery</option>
</select>

Implementazione strategica e best practice

  • USA appearance: base-select quando il tuo sistema di progettazione richiede un'alta fedeltà e una coerenza visiva in tutti i controlli dei moduli che non possono essere ottenute con gli override di selezione cross-browser standard.
  • NON utilizzare questo attributo se ti affidi all'esperienza di selezione nativa del sistema operativo (ad es. il selettore con rotellina di scorrimento standard sui dispositivi iOS). L'attivazione di base-select disattiva i controlli UI mobile nativi a favore dei menu di livello superiore visualizzati sul web.
  • SÌ: verifica che il contrasto dei colori soddisfi gli standard WCAG. Il selettore personalizzabile ti consente di impostare colori ad hoc, ma è tua responsabilità assicurarti che il testo rimanga leggibile sugli sfondi personalizzati.
  • Testa il comportamento del layout. L'impostazione appearance: base-select rimuove il comportamento predefinito del browser di ridimensionare l'elemento select in base alla larghezza dell'opzione più lunga. Potresti dover impostare una larghezza fissa o utilizzare vincoli flex/grid per evitare variazioni del layout.
  • Assicurati che il tuo <select> abbia un attributo name e un <label> associato. In questo modo, anche con una UI personalizzata, il componente rimane accessibile agli screen reader e funziona correttamente con gli invii di moduli standard.
  • Utilizza gli attributi value standard sulle opzioni per assicurarti che l'invio del modulo funzioni esattamente come prima.

Strategie di riserva

Opzioni di riserva e supporto dei browser per <select> personalizzabile

Per i browser che non supportano ancora appearance: base-select, l'elemento <select> si riduce correttamente a un menu a discesa del sistema operativo standard.

  • Contenuti non testuali ignorati: i browser meno recenti rimuovono i tag HTML (come <svg> o <div>) all'interno dei tag <option> ed eseguono il rendering solo dei nodi di testo. Assicurati che i contenuti testuali di <option> siano leggibili e significativi di per sé.
  • Gestione della struttura HTML: i parser standard potrebbero ignorare i tag <button> e <selectedcontent> all'interno di <select> o trattarli come non validi. Per il potenziamento progressivo non sono strettamente necessari polyfill JavaScript pesanti se consideri il testo standard come un fallback leggibile.
document.addEventListener("DOMContentLoaded", () => {
  // Check if browser supports base-select value
  if (!CSS.supports("appearance", "base-select")) {
    // Custom select overrides are not supported natively.
  }
});