HOWTO · CSS
Styliser un menu déroulant en CSS
Ce tutoriel présente comment styliser le menu déroulant en CSS.
Sur cette page
Vous pouvez styliser une liste déroulante HTML native select en modifiant son apparence et en remplaçant sa flèche par défaut par une flèche dessinée en CSS. Le contrôle reste un véritable élément select : les utilisateurs conservent ainsi son comportement de sélection intégré et son interaction au clavier. Deux méthodes courantes consistent à supprimer directement son apparence native ou à masquer la flèche native avec un conteneur qui la rogne.
Styliser une liste déroulante native tout en conservant son comportement
Un élément select contient des éléments option, et le navigateur affiche le contrôle selon les conventions de sa plateforme et de son navigateur. Le CSS peut modifier l’apparence visible du contrôle, mais la liste qui s’ouvre et certains détails varient encore selon les navigateurs et les systèmes d’exploitation. Pour conserver le comportement intégré des formulaires et la prise en charge du clavier, gardez l’élément natif au lieu de recréer une liste déroulante à partir d’éléments génériques.
Les exemples utilisent les mêmes quatre choix. Leur CSS réserve de l’espace à droite du contrôle pour une flèche et ajoute un contour de focus visible pour les personnes qui utilisent le clavier. Ajustez les couleurs et les dimensions pour les adapter à votre interface.
Masquer la flèche native avec appearance: none et ajouter une flèche personnalisée
Définissez appearance: none sur le select pour supprimer la flèche native du navigateur lorsque cette propriété est prise en charge, puis dessinez un chevron à l’aide de deux dégradés CSS. Les couches background placent les deux traits près du bord droit ; une marge intérieure à droite évite que le texte des options ne passe dessous. Les déclarations -webkit-appearance et -moz-appearance sont des variantes préfixées destinées aux moteurs qui utilisent ces préfixes ; elles ne correspondent pas à des familles de navigateurs WebKit et Blink distinctes. La propriété standard reste la déclaration principale : ne conservez les préfixes que si les exigences de compatibilité de vos navigateurs le justifient.
Cette page complète est un exemple statique destiné au navigateur. Enregistrez-la dans un fichier HTML et ouvrez-la dans un navigateur pour voir le contrôle ; les éléments fournis ne comprennent aucune preuve de rendu dans un navigateur qui permettrait d’affirmer un résultat visuel.
Le code et les libellés ou sorties affichés dans cette section restent en anglais.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Styled select</title>
<style>
.vehicle-select {
box-sizing: border-box;
width: 220px;
height: 40px;
padding: 0 32px 0 10px;
border: 1px solid #777;
border-radius: 4px;
color: #222;
background-color: #fff;
background-image:
linear-gradient(45deg, transparent 50%, #333 50%),
linear-gradient(135deg, #333 50%, transparent 50%);
background-position:
calc(100% - 14px) 50%,
calc(100% - 9px) 50%;
background-size: 5px 5px, 5px 5px;
background-repeat: no-repeat;
appearance: none;
}
.vehicle-select:focus-visible {
outline: 3px solid #1769aa;
outline-offset: 2px;
}
</style>
</head>
<body>
<label for="vehicle">Choose a vehicle</label>
<select class="vehicle-select" id="vehicle" name="vehicle">
<option>RE Himalayan</option>
<option selected>CRF Rally</option>
<option>GS 310</option>
<option>KTM ADV</option>
</select>
</body>
</html>
Masquer la flèche native avec un conteneur qui la rogne
Un conteneur offre une autre façon de masquer la flèche native. Donnez au select une largeur légèrement supérieure à celle du conteneur et définissez overflow sur hidden pour ce dernier : la flèche native se retrouve alors hors de la zone visible. Dessinez une flèche de remplacement sur le conteneur avec un pseudo-élément. Comme le select reste à l’intérieur du conteneur, ses choix et son interaction native restent disponibles.
Prévoyez une largeur de conteneur suffisante pour le texte du contrôle, et ne rendez le select que légèrement plus large. Si l’écart est trop important, le bord droit du contrôle ou d’autres éléments risquent aussi d’être rognés. Le pseudo-élément utilise pointer-events: none pour ne pas intercepter les clics sur le select.
Dans l’exemple avec conteneur, le select dépasse de 20 pixels. Cette petite vérification JavaScript rend explicite cette relation entre les largeurs :
Le code et les libellés ou sorties affichés dans cette section restent en anglais.
const wrapperWidth = 200;
const selectWidth = 220;
if (selectWidth <= wrapperWidth) {
process.exitCode = 1;
}
La vérification réussit lorsque le select est plus large que le conteneur ; dans le cas contraire, elle définit un code de sortie signalant un échec.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Select with clipped arrow</title>
<style>
.select-wrap {
position: relative;
box-sizing: border-box;
width: 200px;
height: 42px;
overflow: hidden;
border: 1px solid #777;
border-radius: 4px;
background: #fff;
}
.select-wrap select {
box-sizing: border-box;
width: 220px;
height: 40px;
padding: 0 10px;
border: 0;
color: #222;
background: transparent;
font: inherit;
}
.select-wrap::after {
position: absolute;
top: 18px;
right: 12px;
width: 7px;
height: 7px;
border-right: 2px solid #333;
border-bottom: 2px solid #333;
content: "";
pointer-events: none;
transform: rotate(45deg);
}
.select-wrap:focus-within {
outline: 3px solid #1769aa;
outline-offset: 2px;
}
</style>
</head>
<body>
<label for="vehicle">Choose a vehicle</label>
<div class="select-wrap">
<select id="vehicle" name="vehicle">
<option>RE Himalayan</option>
<option selected>CRF Rally</option>
<option>GS 310</option>
<option>KTM ADV</option>
</select>
</div>
</body>
</html>
Choisir une méthode et en vérifier les limites
Utilisez appearance: none si vous souhaitez que le select définisse lui-même sa largeur et sa bordure, et si les navigateurs ciblés prennent en charge le style nécessaire. Choisissez un conteneur qui rogne le contenu si vous avez besoin d’une flèche au niveau du conteneur ou si le style direct avec appearance ne convient pas. Dans les deux cas, testez la page sur les navigateurs et les appareils pris en charge : le rendu natif du select et ses menus déroulants ne sont pas parfaitement uniformes.
Vérifiez que la valeur sélectionnée reste entièrement visible, que la flèche personnalisée est bien alignée et que le focus clavier est facile à repérer. Avec la version utilisant un conteneur, comparez la largeur du conteneur à celle du select si la bordure ou le texte semble coupé. Ne supprimez pas l’indicateur de focus simplement pour épurer l’apparence du contrôle ; si vous le personnalisez, remplacez-le par un style tout aussi visible. Ces techniques modifient la présentation tout en laissant le select natif gérer la sélection et le comportement du formulaire.