Dropdown Animated
Menu déroulant à apparition en cascade : chaque item glisse de la gauche avec un délai CSS échelonné de 50 ms — basculement de classe unique, zéro dépendance.
Vous aurez accès à la démo interactive avec un compte gratuit.
Cet effet fait partie d'Effect.Labs — 811 effets vanilla, une partie gratuite, une partie premium. Navigation comprend 36 effets, dont 4 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
L'ouverture repose sur un basculement de classe CSS : la fonction JS toggleDropdown() ajoute ou retire la classe active sur le conteneur .anim-dropdown-container. Aucune librairie d'animation n'est impliquée — tout le rendu est piloté par les transition du navigateur.
Le panneau .anim-dropdown-menu passe simultanément de opacity: 0 à 1, de visibility: hidden à visible et de transform: translateY(-10px) à translateY(0) en 0,3 s. L'utilisation de visibility (et non de display: none) préserve la continuité de la transition tout en bloquant les clics et le focus quand le menu est invisible.
L'effet de stagger est entièrement déclaratif en CSS : chaque .anim-dropdown-item part de opacity: 0; transform: translateX(-10px) et transite vers opacity: 1; translateX(0). Les règles :nth-child(1…4) lui assignent des transition-delay de 0,05 s / 0,10 s / 0,15 s / 0,20 s respectivement — le dernier item arrive 200 ms après le début de l'ouverture. Ajouter des items supplémentaires ne demande qu'une règle :nth-child(N) de plus.
La fermeture se déclenche de trois façons : re-clic sur le bouton déclencheur, clic en dehors du conteneur (écouteur document click qui vérifie contains(e.target)), ou pression de la touche Échap. L'icône chevron tourne de 180° via transform: rotate(180deg) sur .anim-dropdown-container.active .anim-dropdown-icon.
Accessibilité
- prefers-reduced-motion non pris en charge : le code ne contient aucun test
matchMedia('(prefers-reduced-motion: reduce)')— les transitions CSS restent actives quel que soit le paramètre OS. Ajoutez manuellement@media (prefers-reduced-motion: reduce) { .anim-dropdown-menu, .anim-dropdown-item { transition: none } }pour les utilisateurs sensibles. - Le bouton déclencheur est un
<button>natif : l'activation au clavier (Entrée / Espace) fonctionne sans code supplémentaire. La touche Échap ferme le menu (gérée dans le JS via écouteurkeydown). - aria-expanded et aria-haspopup absents du code fourni : à ajouter manuellement sur le
<button>(aria-expanded="false"basculé en"true"à l'ouverture,aria-haspopup="menu") pour que les lecteurs d'écran annoncent l'état du menu. - Les items du menu sont des
<div>non focusables : ils ne sont pas accessibles à la tabulation ni aux touches fléchées. Pour une navigation clavier complète, remplacez-les par des<button>ou des<a>. - Contraste : texte
rgba(255,255,255,.7)sur fondrgba(30,30,45,.98)— le rapport dépasse 4,5:1 WCAG AA. Le hover en indigo (rgba(99,102,241,.2)) ne dégrade pas le texte blanc.
Compatibilité navigateur
Utilise uniquement les CSS Transitions et classList — disponibles dans tous les navigateurs modernes sans préfixe vendor. Zéro dépendance externe.
Sans JS, le bouton est visible mais le menu ne s'ouvre pas. Repli HTML pur possible en remplaçant le conteneur par un <code><details></code>/<code><summary></code> natif — aucune animation, mais fonctionnel sans script.
Le code
Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :
<div class="anim-dropdown-container" id="dropdown">
<button class="anim-dropdown-trigger" onclick="toggleDropdown()">
Libellé
<svg class="anim-dropdown-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M6 9l6 6 6-6"></path>
</svg>
</button>
<div class="anim-dropdown-menu">
<div class="anim-dropdown-item">
<svg class="anim-dropdown-item-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">…</svg>
Item 1
</div>
<!-- Pour chaque item supplémentaire, ajouter dans le CSS :
.anim-dropdown-container.active .anim-dropdown-item:nth-child(N) { transition-delay: Xs } -->
</div>
</div>
HTML + CSS + JS complet, prêt à coller — avec des centaines d'effets premium.
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
| transition-delay :nth-child(N) | 0,05 s par item | Délai échelonné par item — règles CSS .active .anim-dropdown-item:nth-child(1…4). Augmentez à 0,08 s pour un stagger plus marqué, réduisez à 0,02 s pour une apparition quasi-simultanée. |
| transition: opacity .3s … (menu) | 0,3 s | Durée d'ouverture du panneau entier — 0,2 s pour un menu vif, 0,45 s pour un rendu plus souple. |
| transform: translateY(-10px) (menu) | -10px | Décalage vertical du panneau à l'état fermé. Passez à -20 px pour un effet de chute plus prononcé, ou remplacez par scaleY(0.92) pour un effet de dépliage. |
| transform: translateX(-10px) (items) | -10px | Décalage horizontal de chaque item avant apparition. Remplacez par translateY(8px) pour une apparition de bas en haut. |
| .anim-dropdown-item:hover background | rgba(99,102,241,.2) | Couleur de survol des items (indigo par défaut) — remplacez par la teinte primaire de votre interface. |
| min-width sur .anim-dropdown-menu | 200px | Largeur minimale du panneau — portez à 260 px pour des labels longs ou un menu à deux colonnes. |
| Items supplémentaires | 4 items | Pour chaque item ajouté, déclarez .anim-dropdown-container.active .anim-dropdown-item:nth-child(N) { transition-delay: Xs } avec Xs = 0,05 × N. |
FAQ
getElementById('dropdown') et une fonction globale toggleDropdown() — une seule instance par page. Pour plusieurs menus, modifiez la fonction en lui passant l'id : function toggleDropdown(id) { document.getElementById(id).classList.toggle('active'); }, puis appelez onclick="toggleDropdown('menu-1')" sur chaque bouton avec l'id correspondant.isOpen via useState et conditionnez className. Dans Vue, utilisez :class="{ active: isOpen }" sur le conteneur. Dans Svelte, class:active={isOpen} suffit. Le CSS stagger ne change pas — seul le pilotage de la classe diffère.active. Pour une fermeture différente (ex. fondu rapide sans glissement), ajoutez temporairement une classe closing via JS avant de retirer active et définissez .closing .anim-dropdown-menu { transition: opacity .15s; } — puis retirez closing après le délai via setTimeout.