HTML fournit un moyen natif de créer une boîte de sélection qui prend en charge la sélection de plusieurs éléments avec l’attribut multiple sur les éléments de sélection, mais le rendu de ceci n’est vraiment pas très compact ou joli, et il n’y a pas beaucoup de choses que vous pouvez faire en termes de style avec les options dans une boîte de sélection non plus. Je n’ai pas trouvé de design personnalisé qui correspondait au style que je recherchais, alors j’ai fini par créer le mien. Le code complet est disponible sur mon GitHub ici ainsi qu’une barre de recherche correspondante.
Ceci est construit à partir de zéro en raison des difficultés à modifier le comportement et le style d’une sélection normale. La partie normalement visible du select est un simple bouton. Le menu déroulant est un div caché par la classe utilitaire Bootstrap d-none, avec un arrondi et un ombrage appliqués via les classes utilitaires Bootstrap shadow et rounded. Les options sont de simples cases à cocher avec des étiquettes. Elles pourraient être remplacées par des boutons radio si vous vouliez une seule boîte de sélection correspondante.
Voici le HTML final pour le bouton et le menu
<div> <button onclick="dropDown(event);" class="menu-btn" type="button"> Menu 1 ⌵ </button> <div class="d-none shadow rounded menu"> <span class="d-block menu-option"><label><input type="checkbox"> Option 1</label></span> <span class="d-block menu-option"><label><input type="checkbox"> Option 2</label></span> <span class="d-block menu-option"><label><input type="checkbox"> Option 3</label></span> </div></div>
Je voulais que le bouton du menu soit arrondi et assez petit, je l’ai donc stylisé en conséquence (vous pouvez styliser comme vous le souhaitez bien sûr, cela n’affecte pas du tout la fonction) :
.menu-btn { border-radius: 48px; border: 0.5px solid lightgrey; font-size: 0.9em; padding: 2px 10px; background-color: white;}
Pour le menu lui-même, j’ai ajouté un peu de padding pour que le texte ne bute pas sur le haut du menu et une certaine marge pour qu’il ne chevauche pas le bouton (les deux sont complètement optionnels). J’ai également ajouté un z-index élevé (pour qu’il s’affiche par-dessus d’autres choses), une couleur d’arrière-plan (la valeur par défaut est transparente, ce qui semble idiot dans ce contexte), et j’ai défini la position à absolue pour qu’il ne pousse pas d’autres choses vers le bas de la page.
.menu { padding-top: 10px; z-index: 200; margin-top: 4px; background-color: white; position: absolute;}
Pour les options du menu, j’ai ajouté un peu de rembourrage pour les séparer.
.menu-option { padding: 6px 20px 6px;}
Nous avons besoin d’un moyen de détecter quand les clics sont faits en dehors du menu déroulant afin qu’il puisse être rejeté en cliquant à l’extérieur comme une boîte de sélection normale. J’ai fait cela en créant une div qui couvre tout l’écran avec un z-index inférieur à celui du menu. Cela nous permet de détecter tous les clics en dehors du menu
<div class="d-none" onclick="hide(event)"></div>
#overlay { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; z-index: 100;}
Pour que cela fonctionne réellement, nous avons besoin de fonctions JavaScript pour faire apparaître et disparaître les menus et la superposition.
Cette fonction supprime les classes d-none du menu et de la superposition, les activant. Plutôt que de gérer cela via l’ID, elle prend simplement le deuxième élément du parent de la cible (du bouton) et suppose que c’est le menu. C’est la raison pour laquelle le menu et le bouton sont enveloppés dans un div autrement vide.
function dropDown(event) { event.target.parentElement.children.classList.remove("d-none"); document.getElementById("overlay").classList.remove("d-none");}
Cette fonction ajoute la classe d-none à l’overlay et à tous les éléments avec la classe menu, les cachant.
function hide(event) { var items = document.getElementsByClassName('menu'); for (let i = 0; i < items.length; i++) { items.classList.add("d-none"); } document.getElementById("overlay").classList.add("d-none");}
Si vous avez trouvé cela utile, vous pourriez également aimer mon design de barre de recherche correspondant.