Richiesta di feedback dello sviluppatore: selezione personalizzabile

Lo stile dei controlli dei moduli come l'elemento <select> è stato segnalato come uno dei principali problemi degli sviluppatori da anni e stiamo lavorando a una soluzione. Anche se questo lavoro è complesso e ha richiesto molto tempo per funzionare correttamente, ci stiamo avvicinando molto a questa funzionalità. Una versione personalizzabile dell'elemento select è ufficialmente nella fase 2 del 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 di aver attivato il flag delle funzionalità della piattaforma web sperimentale. 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 dare un'occhiata a questa raccolta Codepen per vederli tutti in un unico posto.

Utilizza questo modulo per fornire un feedback sulla funzionalità. Il completamento dell'operazione richiede solo tre minuti.

Analizziamo le funzionalità dell'API personalizzabile select, che si basa sul tag HTML select 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 pseudo-elemento 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 modalità, come illustrato 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. La nuova selezione personalizzabile è dotata di alcuni stili predefiniti che hanno lo stesso aspetto in tutti i browser e sistemi operativi. Ecco come appare la selezione personalizzata predefinita rispetto alla selezione esistente in Chrome su macOS:

Stile user agent predefinito per la selezione personalizzabile a destra. Queste modifiche sono soggette a variazioni e ci piacerebbe ricevere il tuo feedback.
Demo di un selettore di base rispetto a un selettore personalizzabile.

Scomporre i pezzi

Diagramma che mostra 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 valore può cambiare). - ::picker(select): popup contenente tutti i contenuti esterni a button all'interno di un selettore personalizzabile.

Puoi definire qualsiasi parte della selezione. 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 definire lo stile di button, personalizzare l'indicatore della freccia e aggiungere contenuti arbitrari all'interno e intorno a uno degli elementi. Oltre ad aggiungere contenuti, puoi nascondere uno qualsiasi di questi nuovi elementi e stili predefiniti. Ad esempio, se non vuoi che venga visualizzato un segno di spunta nello pseudoelemento ::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 utilizzare il tuo wrapper per lo 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à del popover e del posizionamento di ancoraggio. Si basa su 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 degli ancoraggi per applicare uno stile a questo popover ::picker(select) (ad esempio per renderlo ancorato ad altri elementi). Questo modello dei contenuti significa anche che gli stili di animazione del livello superiore funzionano con l'elenco di opzioni per animare gli effetti di ingresso e 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 vantaggi principali del riutilizzo dell'elemento <select> esistente è la possibilità di migliorare progressivamente l'elemento HTML di base. Rispetto a un nuovo elemento, riutilizzo di <select> comporterà comunque il rendering dei contenuti significativi sulla tua pagina. L'esempio seguente mostra la selezione personalizzata a confronto con 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 selezionato.

Stile 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 delle varie parti della selezione con il pulsante predefinito.

Per personalizzare l'indicatore della 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>

Quindi, personalizza la 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 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 flag.

Un esempio più complesso potrebbe includere foto del profilo, nomi e informazioni alternative per aiutarti a prendere decisioni su 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 a come appare nel menu a discesa. Un esempio è l'interfaccia utente di Gmail, dove, per risparmiare spazio, l'etichetta viene rimossa una volta selezionata l'opzione. Per farlo, collega l'elemento <selectedoption> per applicare lo stile. <option> contiene tutti i seguenti 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 di ::picker(select), puoi basarti sulla demo precedente per renderla interattiva 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 che vengono mostrati progressivamente al passaggio del mouse o nello stato attivo.

Limitazioni e note sull'accessibilità

Da un grande potere derivano grandi responsabilità. Per mantenere l'accesso, ci sono alcune limitazioni a questa funzionalità.

  • 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 ora, il modello dei 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 elaboriamo una soluzione accessibile.

In futuro, si prevede che il modello dei contenuti si espanderà in modo più flessibile, man mano che il percorso di accessibilità relativo a queste esperienze verrà arricchito.

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 qualcosa che non funziona come previsto, faccelo sapere.

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

Ti ringraziamo per il tuo contributo nell'aiutarci a risolvere i problemi e a semplificare la creazione di controlli dei moduli accessibili e personalizzabili sul web.