Styliser un <select> en CSS pur, c’est enfin possible !

Menu déroulant stylisé avec plusieurs options humoristiques telles que "WOW!", "SO DROPDOWN!", "VERY SELECT!", accompagné du logo de Google Chrome et du numéro de version "135" sur un fond sombre.

C’est assez relou de devoir implémenter une librairie Javascript juste pour pouvoir styliser le <select> n’est-ce pas ? Bonne nouvelle ! Depuis la version 135 de Chrome, c’est désormais possible de styliser l’élément <select> avec du CSS.

Démonstration tirée d’un CodePen créé par Adam.

Comment ça marchait avant ?

L’élément <select> est un élément natif qui est contrôlé par le système d’exploitation. Lorsqu’on charge une page, votre navigateur demande à votre système d’exploitation de charger le <select> ce qui donnait un <select> avec l’apparence géré par votre système d’exploitation.

Ce n’était donc pas le navigateur qui se chargeait du rendu du <select>, mais plutôt le système d’exploitation. D’où le fait que le même <select> sur le même site pouvait avoir une apparence différente, selon les appareils.

Et comme le navigateur n’avait pas vraiment la main sur son apparence, il était impossible de le styliser proprement avec du CSS. Pour contourner ça, il fallait soit le recréer soit même avec Javascript, soit utiliser des librairies comme Select2, qui remplaçaient le <select> natif par une version customisable.

En quoi la nouvelle version de Chrome résout ce problème ?

Désormais, avec la nouvelle version 135 de Chrome, il est désormais possible de modifier l’apparence du <select> directement via CSS.

Votre navigateur ne fera plus appel au système d’exploitation pour le rendu du <select> mais privilégiera l’apparence que vous aurez définie dans votre code CSS.

Donc logiquement vous n’aurez plus besoin de librairie, désormais nous pouvons personnaliser avec du CSS !

Comment ça marche ?

Propriété base-select.

Une nouvelle propriété CSS fait son apparition : base-select.

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

Cette nouveauté va vous permettre de personnaliser le select. Outre le fait que cette nouvelle propriété nous permettra de personnaliser notre select, mais également va empêcher le menu déroulant de s’afficher en dehors de la zone de fenêtre (viewport).

Parmi les nouveautés de cette nouvelle version de Chrome, vous pouvez également modifier certains éléments liés au select. Notamment la personnalisation de la petite flèche dans le select avec le pseudo élément picker-icon.

select::picker-icon{
  color: red;
}

Comment parler de personnalisation du select sans parler de la personnalisation du menu déroulant ? Le pseudo élément picker() vous permet de personnaliser le menu déroulant.

select::picker(select){
  background-color: grey;
  color: white;
  padding: 5px;
}

Mettre de l’HTML dans les options

Avant, ce n’était pas possible d’intégrer du contenu HTML dans les options car le navigateur l’ignorait, désormais il est tout à fait possible d’y mettre !

    <select name="pays" id="pays">
        <option value="france">
            <img src="https://flagpedia.net/data/flags/w580/fr.webp" alt="Drapeau de la France" width="32px" height="32px">
            France
        </option>
        <option value="belgique">
            <img src="https://flagpedia.net/data/flags/w580/be.webp" alt="Drapeau de la Belgique" width="32px" height="32px">
            Belgique
        </option>
        <option value="pays-bas">
            <img src="https://flagpedia.net/data/flags/w580/nl.webp" alt="Drapeau des Pays-Bas" width="32px" height="32px">
            Pays-Bas
        </option>
    </select>

Dans l’exemple ci-dessus, j’ai mis les drapeaux respectifs à côté des noms des pays. Voici ce que ça donne du côté navigateur.

Menu déroulant de sélection de pays avec des drapeaux : la France (sélectionnée avec une coche), la Belgique et les Pays-Bas. Chaque option est accompagnée du drapeau correspondant et du nom du pays en français.

Est-ce compatible avec tous les navigateurs ?

La mauvaise nouvelle c’est que cette nouveauté n’est pas encore démocratisé sur tous les navigateurs. En revanche, la bonne nouvelle c’est que, ça va se démocratiser progressivement.

C’est encore un petit pas, certes, mais c’est déjà une avancée significative pour tous les développeurs qui souhaitent styliser un <select> sans dépendre d’une librairie.