Richiesta di feedback dello sviluppatore: selezione personalizzabile

La definizione dello stile dei controlli dei moduli, come l'elemento <select>, è stata segnalata come uno dei principali pain point degli sviluppatori per anni e abbiamo lavorato a una soluzione. Sebbene questo lavoro sia complesso e abbia richiesto molto tempo per essere perfezionato, siamo molto vicini al lancio di questa funzionalità. Una versione personalizzabile dell'elemento select è ufficialmente nella Fase 2 del WHATWG, con un forte interesse cross-browser e un prototipo da testare a partire da Chrome Canary 130.

Provala e inviaci il tuo feedback

Verifica che l'installazione di Chrome Canary sia aggiornata alla versione 130 e che il flag delle funzionalità della piattaforma web sperimentale sia attivo. Puoi attivare questo flag andando su chrome://flags nella barra degli indirizzi e attivando #experimental-web-platform-features. Dopodiché, dovresti essere in grado di visualizzare le demo di Codepen in questo post. In alternativa, puoi consultare questa raccolta di Codepen per visualizzarli tutti in un unico posto.

Utilizza questo modulo per fornire un feedback sulla funzionalità. Ci vorranno solo tre minuti per completarlo.

Esaminiamo le funzionalità dell'API select personalizzabile, che si basa sul tag select HTML esistente.

Attivazione del nuovo <select>

Per attivare il nuovo comportamento, utilizza la proprietà CSS appearance sia sul pulsante di selezione in-page sia sul selettore. Per attivare questa funzionalità, imposta appearance: base-select sull'elemento <select> e su ::picker(select).

::picker(select) è un nuovo pseudo-elemento fornito dallo user agent che si applica solo agli elementi <select> che hanno attivato il nuovo comportamento utilizzando appearance: base-select. Questo pseudo-elemento del selettore è il popover attivato dal pulsante di selezione di base. Puoi attivarli entrambi come mostrato nel seguente codice:

select,
::picker(select) {
  appearance: base-select;
}

Puoi scegliere di attivare solo il pulsante in-page, ma non puoi attivare solo il popover del selettore senza attivare il pulsante in-page. ::picker(select) viene creato solo dopo che appearance: base-select è stato applicato a <select>.

Ora puoi personalizzare l'elemento select. Il nuovo elemento select personalizzabile include alcuni stili predefiniti che hanno lo stesso aspetto su browser e sistemi operativi. Ecco come appare l'elemento select personalizzato predefinito rispetto all'elemento select esistente in Chrome su macOS:

Stile dello user agent predefinito per l'elemento select personalizzabile a destra. Questo aspetto è soggetto a modifiche e ci piacerebbe ricevere il tuo feedback in merito.
Demo di un elemento select di base rispetto a un elemento select personalizzabile.

Analisi delle parti

Diagramma che mostra le parti di un elemento select.

Una volta attivata la nuova modalità di selezione personalizzabile, i nuovi elementi a cui hai accesso includono: - selectedoption: riflette l'HTML interno dell'opzione attualmente selezionata. - option::before: contiene un segno di spunta per indicare l'opzione attualmente selezionata come affordance di accessibilità predefinita (questo è soggetto a modifiche). - ::picker(select): popover che contiene tutti i contenuti esterni a button all'interno di un elemento select personalizzabile.

Puoi applicare uno stile a qualsiasi parte della selezione. Ad esempio, puoi aggiungere contenuti non interattivi arbitrari all'interno degli elementi <option>, applicare uno stile al pulsante in-page che apre il menu a discesa di selezione e applicare uno stile all'elenco a discesa delle opzioni (::picker(select)).

Puoi anche applicare uno stile a button, utilizzare un indicatore a freccia personalizzato e aggiungere contenuti arbitrari all'interno e intorno a uno qualsiasi degli elementi. Oltre ad aggiungere contenuti, puoi nascondere uno qualsiasi di questi nuovi elementi e stili predefiniti. Ad esempio, se non vuoi un segno di spunta dell'indicatore nello pseudo-elemento ::before dell'opzione, utilizza il seguente CSS.

/* Remove the default checkmark from the selected option */
option::before {
 display: none;
}

Sebbene possa esserci un numero illimitato di elementi all'interno del tuo select, il browser raggrupperà tutto ciò che si trova all'esterno di un elemento <button> nello pseudo-elemento ::picker(select), che si comporta come un popover ancorato al pulsante. Questo <button> attiva/disattiva ::picker(select). Le opzioni e gli altri elementi direttamente all'interno della selezione verranno inseriti in ::picker(select) oppure puoi utilizzare il tuo wrapper per scopi di stile. Anche questo wrapper verrà inserito all'interno dello pseudo-elemento ::picker(select).

<select>
  <button>
    <selectedoption></selectedoption>
  </button>
  // Everything else that will go into the ::picker(select) popover
</select>

Il nuovo <select> personalizzabile utilizza le funzionalità di popover e posizionamento degli ancoraggi. È basato su queste due tecnologie. Ciò significa che l'elenco di opzioni del menu a discesa all'interno di un elemento select funge da popover ancorato al pulsante di attivazione che apre l'elemento select.

Puoi utilizzare il posizionamento ancorato per applicare uno stile a questo popover ::picker(select) (incluso l'ancoraggio ad altri elementi). Questo modello di contenuti significa anche che gli stili di animazione del livello superiore funzionano con l'elenco di opzioni per animare gli effetti di entrata e uscita.

Migliora l'elemento <select> esistente

In precedenza, il team di Chrome stava lavorando all'idea di un elemento <selectlist>. In questo post viene descritta la funzionalità riprogettata per riutilizzare l'elemento <select> esistente.

Uno dei principali vantaggi del riutilizzo dell'elemento <select> esistente è la possibilità di applicare il potenziamento progressivo all'elemento HTML di base. Rispetto a un elemento completamente nuovo, il riutilizzo di <select> continuerà a mostrare contenuti significativi sulla tua pagina. L'esempio seguente mostra la selezione personalizzata rispetto a ciò che vedrebbe un utente in un browser non supportato:

Tutti i contenuti testuali all'interno di option vengono visualizzati nella versione di riserva dell'elemento select.

Stile di base

Le modifiche possono essere semplici, come lo stile visivo dell'elemento select. Ad esempio, per aggiornare gli stili dei pulsanti, gli stili di passaggio del mouse e di selezione o lo sfondo delle opzioni di selezione. Dopo aver attivato la funzionalità con appearance: base-select, applica il CSS che preferisci alle parti della selezione.

Modifica degli stili di varie parti della selezione, con il pulsante predefinito.

Per personalizzare l'indicatore a freccia, aggiungi il tuo pulsante e la tua freccia all'interno della selezione.

<select>
  <button>
    <selectedoption></selectedoption>
    <span>
      // Arrow here
    </span>
  </button>
  // Everything else that will go into the ::picker(select) popover
</select>

Poi, applica uno stile alla freccia:

/* style the arrow */
button span {
  /* arrow styles */
  transition: rotate 0.2s;
}

/* adjust arrow styles when the picker is open */
select:open button span {
  rotate: -180deg;
}

Contenuti complessi all'interno delle opzioni

Fai un passo avanti con la possibilità di aggiungere e applicare stili ai contenuti oltre alle stringhe all'interno degli elementi <option> in <select>. Un esempio di base è l'aggiunta di immagini di bandiere accanto ai nomi dei paesi in un menu a discesa. Per farlo, aggiungi un elemento immagine accanto al testo dell'opzione.

<option value="france">
  <img src="img/flag_of_france.svg" alt="" />
  <span>France</span>
</option>
Selettore del paese con bandiere.

Un esempio più complesso potrebbe includere foto del profilo, nomi e informazioni alternative per aiutarti a decidere quale elemento selezionare nel menu a discesa.

<option value="eur">
    <img src="euro-flag.png" alt="" />
    <div class="currency">
      <div class="currency-short">EUR</div>
      <div class="currency-long">Euro</div>
    </div>
    <div class="symbol" aria-hidden="true">€</div>
</option>
Screenshot del selettore di valuta.

Definisci lo stile dell'opzione selezionata

Potresti voler visualizzare l'opzione selezionata in modo diverso nello stato selezionato rispetto al menu a discesa. Un esempio è l'interfaccia utente di Gmail, in cui, per risparmiare spazio, l'etichetta viene rimossa una volta selezionata l'opzione. Per farlo, utilizza l'elemento <selectedoption> per lo stile. <option> contiene tutto il seguente markup:

 <option value="reply-all">
    <img class="material-symbol"  src="material-symbol-reply.png">
    <span class="text">Reply all</span>
  </option>

Ora applica display: none su .text all'interno di <selectedoption> per nascondere i contenuti di testo e mostrare solo l'icona:

selectedoption .text {
  display: none;
}
Selezione in stile Gmail con un'icona che rappresenta l'opzione selezionata.

Opzioni interattive

Con il controllo completo sullo stile di ::picker(select), basati sulla demo precedente per renderlo interattivo al passaggio del mouse e allo stato attivo. In questa demo, la nuova funzione calc-size() viene utilizzata per animare la larghezza del selettore, passando dalla visualizzazione delle icone alla visualizzazione della larghezza completa delle opzioni al passaggio del mouse o se l'elemento select ha un'opzione con focus-visible.

/* base styles when picker is open but not interacted with */
::picker(select) {
  width: var(--icon-width);
  transition: width 0.5s;
}

/* animate the text in on hover & focus */
::picker(select):hover,
select:has(option:focus-visible)::picker(select) {
  /*  auto width!  */
  width: calc-size(auto, size + 0.5rem);
}
Selezione interattiva in stile Gmail con contenuti mostrati progressivamente al passaggio del mouse o allo stato attivo.

Limitazioni e note sull'accessibilità

Da un grande potere derivano grandi responsabilità. Per mantenere l'accessibilità, la funzionalità presenta alcune limitazioni.

  • Oltre agli elementi <option>, non sono ancora consentiti elementi interattivi (attivabili) all'interno di <select>, come pulsanti o altri elementi. Per il momento, il modello di contenuti proposto consente solo gli elementi <div>, <span>, <option>, <optgroup>, <img>, <svg> e <hr>.
  • I pulsanti di suddivisione sono attualmente in fase di sperimentazione mentre lavoriamo a una soluzione accessibile.

In futuro, si prevede che il modello di contenuti si espanderà per essere più flessibile, man mano che la storia dell'accessibilità per queste esperienze verrà definita.

Conclusione

Siamo entusiasti di vedere questa funzionalità progredire attraverso gruppi di lavoro e organismi di standardizzazione e di condividere i nostri progressi mentre creiamo attivamente il prototipo e valutiamo la forma di questa funzionalità. Se riscontri qualcosa che non funziona come previsto, faccelo sapere.

Anche se questa funzionalità è ancora in fase di sviluppo, ci piacerebbe ricevere il tuo feedback tramite questo breve modulo di feedback.

Grazie per aver contribuito a garantire che tutto funzioni correttamente e a semplificare la creazione di controlli dei moduli accessibili e personalizzabili sul web.