Richiesta di feedback dello sviluppatore: selezione personalizzabile

Lo stile dei controlli dei moduli come l'elemento <select> è stato segnalato come uno dei principali problemi per gli sviluppatori da anni e stiamo lavorando a una soluzione. Sebbene questo lavoro sia complesso e abbia richiesto molto tempo per essere completato, siamo molto vicini al lancio di questa funzionalità. Una versione personalizzabile dell'elemento select è ufficialmente nella fase 2 di WHATWG, con un forte interesse cross-browser e un prototipo che puoi testare da Chrome Canary 130.

Prova la funzionalità e inviaci il tuo feedback

Verifica che l'installazione di Chrome Canary sia aggiornata alla versione 130 e che sia attivato l'indicatore delle funzionalità sperimentali della piattaforma web. Puoi attivare questo flag andando su chrome://flags nella barra degli indirizzi e attivando #experimental-web-platform-features. Dopodiché dovresti riuscire a vedere le demo di Codepen in questo post. In alternativa, puoi consultare questa raccolta di Codepen per visualizzarli tutti in un'unica posizione.

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

Analizziamo le funzionalità dell'API di selezione personalizzabile, che si basa sul tag di selezione 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 di selezione. Per attivare questa funzionalità, imposta appearance: base-select sull'elemento <select> e su ::picker(select).

::picker(select) è un nuovo pseudoelemento fornito dall'agente utente che si applica solo agli elementi <select> per i quali è stato attivato il nuovo comportamento utilizzando appearance: base-select. Questo pseudo-elemento del selettore è il popup attivato dal pulsante di selezione di base. Puoi attivare entrambe le opzioni 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 popup del selettore senza attivare il pulsante in-page. ::picker(select) viene creato solo dopo l'applicazione di appearance: base-select a <select>.

Ora puoi personalizzare l'elemento di selezione. Il nuovo selettore personalizzabile è dotato di alcuni stili predefiniti che hanno lo stesso aspetto su browser e sistemi operativi. Ecco come appare il selettore personalizzato predefinito rispetto al selettore esistente in Chrome su macOS:

Stile user agent predefinito per la selezione personalizzabile a destra. Questo aspetto è soggetto a modifiche e ci farebbe piacere ricevere il tuo feedback.
Demo di un selettore di base rispetto a un selettore personalizzabile.

Suddivisione delle parti

Diagramma che mostra le parti di una selezione.

Una volta attivata la nuova modalità di selezione personalizzabile, avrai accesso ai seguenti nuovi elementi: - selectedoption: riflette l'HTML interno dell'opzione attualmente selezionata. - option::before: contiene un segno di spunta per indicare l'opzione attualmente selezionata come funzionalità di accessibilità predefinita (questo può cambiare). - ::picker(select): popup contenente tutti i contenuti esterni a button all'interno di un selettore personalizzabile.

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

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

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

Sebbene all'interno del selettore possa essere presente un numero illimitato di elementi, il browser raggruppa tutto ciò che non è un elemento <button> nell'elemento pseudo ::picker(select), che si comporta come un popup ancorato al pulsante. Questo <button> attiva/disattiva ::picker(select). Le opzioni e gli altri elementi direttamente all'interno del selettore verranno inseriti in ::picker(select) oppure puoi aggiungere il tuo wrapper per lo stile. Anche questo wrapper verrà inserito all'interno dell'elemento pseudo ::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 dell'ancora. È realizzato con queste due tecnologie di base. Ciò significa che l'elenco di opzioni a discesa all'interno di un selettore agisce come un popup ancorato al pulsante di attivazione che apre il selettore.

Puoi utilizzare il posizionamento dell'ancora per applicare uno stile a questo popup ::picker(select) (ad esempio fissarlo 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 di uscita.

Migliorare 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 migliorare progressivamente l'elemento HTML di base. Rispetto a un elemento nuovo di zecca, il riutilizzo di <select> consente comunque di visualizzare contenuti significativi nella pagina. L'esempio seguente mostra la selezione personalizzata rispetto a ciò che vedrebbe un utente in un browser non supportato:

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

Stili di base

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

Modifica degli stili di varie parti del selettore con il pulsante predefinito.

Per personalizzare l'indicatore di freccia, aggiungi il tuo pulsante e la tua freccia all'interno del selettore.

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

Quindi, applica lo 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

Vai oltre con la possibilità di aggiungere e applicare stili ai contenuti oltre alle stringhe all'interno degli elementi <option> all'interno di <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 dei paesi con le 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 valute.

Personalizza lo stile dell'opzione selezionata

Potresti volere che l'opzione selezionata venga visualizzata in modo diverso nello stato selezionato rispetto al menu a discesa. Un esempio è l'interfaccia utente di Gmail, dove, per risparmiare spazio, l'etichetta viene rimossa una volta selezionata l'opzione. A tale scopo, devi collegarti all'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 a .text all'interno di <selectedoption> per nascondere il contenuto del 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 pieno controllo sullo stile del ::picker(select), sviluppa la 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 dalla visualizzazione delle icone alla visualizzazione dell'intera larghezza delle opzioni al passaggio del mouse o se il selettore 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 la funzionalità accessibile, sono presenti alcune limitazioni.

  • A parte gli elementi <option>, non sono ancora consentiti elementi interattivi (per i quali è possibile impostare lo stato attivo) 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 divisi sono attualmente in fase di sperimentazione mentre cerchiamo di trovare una soluzione accessibile.

In futuro, il modello di contenuti dovrebbe essere ampliato per essere più flessibile, man mano che la storia dell'accessibilità di queste esperienze viene completata.

Conclusione

Siamo entusiasti di vedere questa funzionalità evolversi nei gruppi di lavoro e negli organismi di standardizzazione e di condividere i nostri progressi mentre sviluppiamo attivamente il prototipo e valutiamo la forma di questa funzionalità. Se riscontri un problema, non esitare a contattarci.

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

Grazie per il tuo contributo a questo progetto, che ci aiuterà a creare più facilmente controlli dei moduli accessibili e personalizzabili sul web.