3D✨ Premium

3D Menu Stack

Quatre liens de menu empilés dans un parent en perspective de 600 px, chacun un peu plus loin et plus pâle que le précédent (0, −10, −20, −30 px ; opacité 1 à 0,7) ; l'entrée survolée, touchée ou atteinte au clavier avance de 20 px, glisse de 10 px vers la droite, pivote de −5° et prend un dégradé indigo-violet avec ombre portée, en 0,3 s — une liste dont la profondeur dit l'ordre, en CSS seul.

CSS3DMenu

Mis à jour le

Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. 3D comprend 50 effets, dont 8 gratuits. Découvrir la catégorie →

3 exemples d'usage

Les quatre paliers d'un baptême de plongée — page d'un club de plongée — 3D Menu Stack exemple 1

① Les quatre paliers d'un baptême de plongée — page d'un club de plongée

QuandMenu « Votre première plongée » : « 3 m — prise en main », « 6 m — équilibre », « 12 m — balade », « 20 m — niveau 1 » ; chaque palier plus profond est plus loin et plus pâle, et celui qu'on survole remonte au premier plan avec sa durée et son lieu.
PourquoiLe recul progressif des entrées est littéralement la profondeur : plus on descend la liste, plus le palier est « loin », et le palier choisi remonte vers le plongeur.
RéglagesRacine sans fond sur un décor bleu d'eau, --bg-card: #0c2c45 ; pile de 272 px de large, marge intérieure des entrées de 14 px × 18 px ; dégradé du survol #0ea5e9 → #2563eb ; durée et lieu à droite de chaque entrée, allumés au survol. La scène fait passer la mise en avant d'un palier à l'autre et cède la place à la souris.
Les quatre plats d'un menu dégustation — site d'un restaurant gastronomique — 3D Menu Stack exemple 2

② Les quatre plats d'un menu dégustation — site d'un restaurant gastronomique

Quand« Amuse-bouche », « Saint-Jacques snackées », « Pigeon rôti », « Soufflé au Grand Marnier » dans l'ordre du repas ; le plat survolé avance avec son accord (Champagne brut, Muscadet sur lie, Chinon 2019, Vouvray moelleux).
PourquoiL'ordre du repas se lit dans l'empilement ; le plat qui avance au survol donne une mise en avant sans ouvrir de fiche, et l'accord vin n'apparaît que pour le plat regardé.
RéglagesFond crème, --bg-card: #2b211b, texte en Georgia 15 px ; dégradé du survol bordeaux #7f1d1d → or #a16207, posé sur la couleur de la carte ; pile de 348 px. Sur fond clair, les entrées reculées (70 à 90 % d'opacité) paraissent plus pâles : c'est l'effet voulu.
Quatre services joignables — page contact d'une mairie de 3 000 habitants — 3D Menu Stack exemple 3

③ Quatre services joignables — page contact d'une mairie de 3 000 habitants

Quand« État civil », « Urbanisme », « Écoles et périscolaire », « Police municipale » empilés ; le service survolé avance et affiche son numéro et ses horaires.
PourquoiUne liste courte et hiérarchisée qui gagne du relief sous le pointeur : le visiteur voit tout de suite quel service il est en train de choisir, et le numéro arrive avec lui.
RéglagesFond clair institutionnel, --bg-card: #ffffff, bordure #cbd5e1, texte sombre qui passe au blanc sur le dégradé bleu #1e3a8a → #2563eb (sans transition de couleur, pour ne jamais laisser du blanc sur blanc) ; entrées élargies à 340 px et posées sur la trajectoire de la souris de capture.

Comment ça marche

La racine .fx-0009-root (fond #0a0a0f, 300 px de haut au minimum) définit trois variables : --bg-card: #12121a, --border et --radius-md. Elle centre .menu-stack, une colonne flex (8 px d'écart) qui porte perspective: 600px, et quatre liens <a class="menu-stack-item"> : bloc, texte blanc gras de 14 px, 12 px × 30 px de marge intérieure, fond de carte, bordure fine, transition de 0,3 s sur tout.

La profondeur est écrite entrée par entrée avec :nth-child : la 1re reste à translateZ(0), la 2e recule de 10 px et passe à ×0,98 et 90 % d'opacité, la 3e à −20 px, ×0,96, 80 %, la 4e à −30 px, ×0,94, 70 %. La perspective s'ajoute à l'échelle : mesurées dans Chromium et Firefox, les quatre entrées font 143, 138, 133 et 128 px de large, la pile se resserre vers le bas comme un escalier vu d'en face. Au survol (ou :focus-visible), l'entrée prend translateZ(20px) translateX(10px) rotateY(-5deg), un dégradé #6366f1 → #8b5cf6, une ombre portée vers le bas à gauche et z-index: 10. Cette transformation remplace celle de la ligne :nth-child : plus l'entrée est loin, plus son saut est grand (20 px pour la 1re, 50 px pour la 4e). Mesuré : 4 % des pixels changent au survol de la 2e entrée.

Deux choix d'écriture. Les entrées sont des liens : Tab les atteint, Entrée les suit, et un vrai menu n'a rien à rajouter. Le dégradé du survol est posé sur la couleur de la carte (linear-gradient(…) var(--bg-card)) : un dégradé seul remet la couleur de fond à transparent, et l'entrée qui perd le survol passerait par la transparence pendant 0,3 s, ce qui la ferait pâlir sur une page claire. Les entrées reculées ont une opacité inférieure à 1 : c'est voulu (elles s'effacent avec la distance), mais tout ce qui est posé dessus s'efface avec elles.

Accessibilité

  • Mouvement réduit : sous prefers-reduced-motion: reduce, un bloc limité à .fx-0009-root ne laisse la transition qu'au fond et à l'ombre, et ramène l'entrée choisie à translateZ(0) : elle passe au premier plan d'un coup, sans glisser ni pivoter ; le dégradé et l'ombre la signalent. Mesuré dans Chromium et Firefox : aucune transition de position en cours, 3,5 % de pixels changés au survol (4 % sans la préférence).
  • Clavier : quatre liens, atteints avec Tab ; le focus donne exactement l'état du survol (:focus-visible), plus l'anneau de focus du navigateur. Dans Safari, Tab ne s'arrête sur les liens que si l'option « Appuyer sur Tab pour mettre en évidence chaque élément » est cochée (sinon Option + Tab) — réglage du navigateur, mesuré dans WebKit.
  • Contraste : texte blanc sur #12121a à 18,6:1 ; la 4e entrée, à 70 % d'opacité, garde 9,4:1 sur le fond d'origine. L'entrée survolée descend à 4,47:1 sur l'indigo et 4,2:1 sur le violet #8b5cf6, sous le seuil de 4,5:1 pour du texte gras de 14 px : foncez la fin du dégradé (#7c3aed donne 5,7:1).
  • Toucher : au doigt, l'entrée touchée prend l'état survolé (mesuré en émulation tactile Chromium et dans Firefox), puis le lien est suivi. Mettez une vraie adresse dans chaque href.

Compatibilité navigateur

CSS seul (perspective sur le parent, transform sur chaque entrée, :nth-child, :focus-visible), aucune dépendance. Mesuré dans Chromium 151 et Firefox 153 : mêmes largeurs (143 à 128 px), même survol, même comportement en mouvement réduit, 0 erreur. Chaque entrée est transformée seule dans la perspective de son parent, sans plans 3D imbriqués : le WebKit de Playwright (26.5), qui aplatit les scènes en preserve-3d, rend celle-ci comme Chromium (2 % d'écart, dus au lissage du texte).

Chrome 86+✓ Complet
Firefox 85+✓ Complet
Safari 15.4+✓ Complet (rendu mesuré dans WebKit 26 ; non vérifié sur un vrai Safari)
Edge 86+✓ Complet
Mobile iOS✓ Survol au doigt non vérifié sur un vrai iPhone
Android Chrome✓ Complet

Sans :focus-visible (navigateur ancien), le focus clavier ne met pas l'entrée en avant : l'anneau du navigateur reste. Sans perspective, les entrées ne reculent plus mais gardent leur réduction (×0,98 à ×0,94) et leur pâleur.

Le code

Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :

index.html — structure
<div class="fx-0009-root">
  <div class="demo-3d">
    <div class="menu-stack">   <!-- perspective: 600px -->
      <a class="menu-stack-item" href="#">Menu Item 1</a>
      <a class="menu-stack-item" href="#">Menu Item 2</a>   <!-- −10 px, ×0,98 -->
      <a class="menu-stack-item" href="#">Menu Item 3</a>   <!-- −20 px, ×0,96 -->
      <a class="menu-stack-item" href="#">Menu Item 4</a>   <!-- −30 px, ×0,94 -->
    </div>
  </div>
</div>

Paiement unique, sans abonnement — le code est à toi pour toujours

Personnaliser

Options passées à l'API ou attributs data-* :

Option / propriétéDéfautEffet
Recul des entrées (CSS — translateZ des quatre :nth-child) 0, −10, −20, −30 px Des pas plus grands (0, −25, −50, −75 px) creusent la pile et serrent davantage le bas ; au-delà de −100 px les dernières entrées deviennent petites. Une 5e entrée demande sa propre ligne :nth-child(5).
Pâleur (CSS — opacity des :nth-child) 1 ; 0,9 ; 0,8 ; 0,7 Sous 0,6 le texte de la dernière entrée devient difficile à lire sur fond clair. Mettez 1 partout pour une pile qui recule sans pâlir.
Mouvement au survol (CSS — transform de :hover, :focus-visible) translateZ(20px) translateX(10px) rotateY(-5deg) rotateY(-10deg) accentue l'effet de porte qui s'ouvre ; retirez translateX pour une entrée qui avance sans glisser.
Couleurs (CSS — --bg-card, --border et dégradé du survol) #12121a ; rgba(255, 255, 255, .08) ; #6366f1 → #8b5cf6 Gardez var(--bg-card) après le dégradé : c'est la couleur dessous, celle qui évite le passage par la transparence quand le survol s'arrête.
Perspective (CSS — .menu-stack) 600 px 300 px exagère le recul et le pivot ; 1 200 px les aplatit presque.
Durée (CSS — transition: .3s) 0,3 s La même durée sert à l'aller et au retour ; 0,2 s donne un menu plus nerveux.

FAQ

Au survol, la transformation de l'entrée est remplacée en entier : la 4e passe de translateZ(-30px) scale(.94) à translateZ(20px) sans échelle, soit 50 px d'avancée, quand la 1re n'avance que de 20 px. C'est ce qui fait « remonter » une entrée lointaine. Pour des sauts égaux, ajoutez le recul de chaque entrée dans sa règle de survol (par exemple translateZ(-10px) en plus pour la 2e).
Oui : les entrées sont des liens <a>, atteints au clavier, avec le même relief au focus qu'au survol. Remplacez les href="#" par vos adresses et, pour une navigation principale, entourez la pile d'un <nav aria-label="…">. Gardez quatre à six entrées : au-delà, les dernières reculent tant qu'elles deviennent petites.
Les entrées 2 à 4 ont une opacité de 0,9 à 0,7 : sur le fond sombre d'origine on ne voit qu'un léger effacement, sur un fond clair elles tirent vers le gris. C'est le signe de la distance. Si vous voulez des cartes pleines, mettez opacity: 1 partout et laissez le recul et la réduction dire la profondeur.