Demande de commentaires de développeur: option personnalisable

Depuis des années, le style des commandes de formulaire telles que l'élément <select> est signalé comme un problème majeur pour les développeurs. Nous travaillons sur une solution. Bien que ce travail soit complexe et ait pris beaucoup de temps, nous sommes sur le point de lancer cette fonctionnalité. Une version personnalisable de l'élément select est officiellement en phase 2 dans le WHATWG, avec un intérêt internavigateur important et un prototype que vous pouvez tester à partir de Chrome Canary 130.

Essayez-la et faites-nous part de vos commentaires

Vérifiez que la version 130 de Chrome Canary est installée et que le commutateur des fonctionnalités expérimentales de la plate-forme Web est activé. Pour activer ce flag, accédez à chrome://flags dans la barre d'adresse et activez #experimental-web-platform-features. Vous devriez alors pouvoir voir les démonstrations Codepen de cet article. Vous pouvez également consulter cette collection Codepen pour les afficher tous au même endroit.

Utilisez ce formulaire pour nous faire part de vos commentaires sur cette fonctionnalité. Cela ne vous prendra que trois minutes.

Examinons les fonctionnalités de l'API select personnalisable, qui s'appuie sur la balise select HTML existante.

Activer la nouvelle <select>

Pour activer le nouveau comportement, utilisez la propriété CSS appearance à la fois sur le bouton de sélection sur la page et sur le sélecteur de sélection. Pour activer cette option, définissez appearance: base-select sur votre élément <select> et sur ::picker(select).

::picker(select) est un nouveau pseudo-élément fourni par l'user-agent qui ne s'applique qu'aux éléments <select> pour lesquels le nouveau comportement a été activé à l'aide de appearance: base-select. Ce pseudo-élément de sélecteur est le pop-up déclenché par le bouton de sélection de base. Vous pouvez activer les deux, comme indiqué dans le code suivant:

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

Vous pouvez choisir d'activer uniquement le bouton sur la page, mais vous ne pouvez pas activer uniquement le pop-up du sélecteur sans activer le bouton sur la page. ::picker(select) n'est créé que lorsque appearance: base-select est appliqué à <select>.

Vous êtes maintenant prêt à personnaliser votre élément de sélection. La nouvelle sélection personnalisable est fournie avec des styles par défaut qui se ressemblent dans tous les navigateurs et systèmes d'exploitation. Voici à quoi ressemble la sélection personnalisée par défaut par rapport à la sélection existante dans Chrome sur macOS:

Style par défaut de l'user-agent pour la sélection personnalisable à droite. Nous aimerions connaître votre avis à ce sujet.
Démonstration d'une sélection de base par rapport à une sélection personnalisable.

Décomposer les éléments

Schéma illustrant les différentes parties d'un sélecteur

Une fois dans le nouveau mode de sélection personnalisable, vous avez accès aux nouveaux éléments suivants : - selectedoption: reflète le code HTML interne de l'option actuellement sélectionnée. - option::before: contient une coche pour indiquer que l'option actuellement sélectionnée est une affordance d'accessibilité par défaut (cela est susceptible d'évoluer). - ::picker(select): popover contenant tout le contenu en dehors de button dans une sélection personnalisable.

Vous pouvez styliser n'importe quelle partie de la sélection. Par exemple, vous pouvez ajouter un contenu non interactif arbitraire dans les éléments <option>, styliser le bouton sur la page qui ouvre le menu déroulant de sélection et styliser la liste déroulante d'options (::picker(select)).

Vous pouvez également styliser l'button, l'indicateur de flèche à apporter, et ajouter du contenu arbitraire à l'intérieur et autour de l'un des éléments. En plus d'ajouter du contenu, vous pouvez masquer l'un de ces nouveaux éléments et styles par défaut. Par exemple, si vous ne souhaitez pas d'indicateur de coche dans le pseudo-élément ::before de l'option, utilisez le code CSS suivant.

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

Bien que vous puissiez inclure un nombre illimité d'éléments dans votre sélecteur, le navigateur regroupe tout ce qui se trouve en dehors d'un élément <button> dans le pseudo-élément ::picker(select), qui se comporte comme un popover ancré au bouton. Ce <button> active/désactive ::picker(select). Les options et les autres éléments directement dans le sélecteur seront hissés dans ::picker(select), ou vous pouvez apporter votre propre wrapper à des fins de style. Ce wrapper sera également placé dans le pseudo-élément ::picker(select).

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

Le nouveau <select> personnalisable utilise les fonctionnalités du popover et du positionnement des ancres. Il est conçu avec ces deux technologies sous-jacentes. Cela signifie que la liste déroulante d'options d'un sélecteur agit comme un pop-up ancré au bouton de déclenchement qui ouvre le sélecteur.

Vous pouvez utiliser le positionnement d'ancrage pour styliser ce pop-up ::picker(select) (y compris en l'ancrant à d'autres éléments). Ce modèle de contenu signifie également que les styles d'animation de la couche supérieure fonctionnent avec la liste d'options pour animer les effets d'entrée et de sortie.

Améliorer l'élément <select> existant

Auparavant, l'équipe Chrome travaillait sur l'idée d'un élément <selectlist>. Ce post décrit la refonte de cette fonctionnalité pour réutiliser l'élément <select> existant.

L'un des principaux avantages de la réutilisation de l'élément <select> existant est la possibilité d'améliorer progressivement l'élément HTML de base. Par rapport à un élément entièrement nouveau, la réutilisation de <select> permet toujours d'afficher du contenu pertinent sur votre page. L'exemple suivant montre la sélection personnalisée par rapport à ce qu'un utilisateur dans un navigateur non compatible verrait:

Tout le contenu textuel de option est affiché dans la version de remplacement de l'élément de sélection.

Style de base

Les modifications peuvent être aussi simples que le style visuel de l'élément de sélection. Par exemple, pour modifier les styles de boutons, les styles de survol et de mise au point, ou l'arrière-plan des options de sélection. Après avoir activé appearance: base-select, appliquez le CSS de votre choix aux parties de votre sélection.

Modification des styles de différentes parties de la sélection, avec le bouton par défaut.

Pour personnaliser l'indicateur de flèche, ajoutez votre propre bouton et votre propre flèche dans la sélection.

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

Modifiez ensuite le style de la flèche:

/* 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;
}

Contenu complexe dans les options

Allez plus loin en ajoutant et en stylisant du contenu au-delà des chaînes dans les éléments <option> de <select>. Un exemple simple est l'ajout d'images de drapeaux à côté des noms de pays dans un menu déroulant. Pour ce faire, ajoutez un élément image à côté du texte de l'option.

<option value="france">
  <img src="img/flag_of_france.svg" alt="" />
  <span>France</span>
</option>
Sélecteur de pays avec des drapeaux.

Un exemple plus complexe peut inclure des photos de profil, des noms et d'autres informations pour vous aider à choisir l'élément à sélectionner dans le menu déroulant.

<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>
Capture d'écran du sélecteur de devise.

Mettre en forme l'option sélectionnée

Vous pouvez souhaiter que l'option sélectionnée s'affiche différemment dans l'état sélectionné que dans le menu déroulant. L'UI de Gmail en est un exemple. Pour économiser de l'espace, le libellé est supprimé une fois l'option sélectionnée. Pour ce faire, utilisez l'élément <selectedoption> pour le style. <option> contient l'ensemble des balises suivantes:

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

Appliquez maintenant display: none sur .text dans <selectedoption>' pour masquer le contenu textuel et n'afficher que l'icône:

selectedoption .text {
  display: none;
}
Sélection de type Gmail avec une icône représentant l'option sélectionnée.

Options interactives

Vous pouvez contrôler entièrement le style de la ::picker(select). Pour la rendre interactive lorsque l'utilisateur la survole ou la met en surbrillance, améliorez la démonstration précédente. Dans cette démonstration, la nouvelle fonction calc-size() permet d'animer la largeur du sélecteur afin de passer de l'affichage des icônes à l'affichage de la largeur complète des options lorsque l'utilisateur pointe dessus ou si le sélecteur comporte une option avec 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);
}
Sélection interactive de type Gmail avec un contenu affiché progressivement lorsque vous pointez ou lorsque vous êtes en mode focus.

Limites et remarques sur l'accessibilité

Un grand pouvoir implique de grandes responsabilités. Pour des raisons d'accessibilité, cette fonctionnalité est limitée.

  • À l'exception des éléments <option>, aucun élément interactif (sélectionnable) n'est encore autorisé dans le <select>, comme les boutons ou d'autres éléments. Pour le moment, le modèle de contenu proposé n'autorise que les éléments <div>, <span>, <option>, <optgroup>, <img>, <svg> et <hr>.
  • Les boutons fractionnés sont actuellement en phase de test, car nous cherchons une solution accessible.

À l'avenir, le modèle de contenu devrait être étendu pour être plus flexible, à mesure que l'accessibilité de ces expériences sera développée.

Conclusion

Nous sommes ravis de voir cette fonctionnalité progresser grâce aux groupes de travail et aux organismes de normalisation, et de partager nos progrès à mesure que nous développons activement le prototype et évaluons la forme de cette fonctionnalité. Si vous rencontrez un problème, n'hésitez pas à nous en informer.

Cette fonctionnalité est encore en cours de développement, mais nous aimerions avoir votre avis à son sujet en remplissant ce court formulaire de commentaires.

Merci de nous avoir aidés à bien faire les choses et à faciliter la création de commandes de formulaire accessibles et personnalisables sur le Web.