Cube Flip
Carré de 40 px, dégradé indigo → violet, deux culbutes de 180° enchaînées (axe X puis axe Y) en 1,2 s, perspective inline de 120 px — un seul div, zéro JS.
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. Chargement comprend 29 effets, dont 4 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
L'effet tient en un seul élément : .loader-cube, carré de 40 × 40 px, fond linear-gradient(135deg, #6366f1, #8b5cf6) (indigo → violet). Aucun enfant, aucun JavaScript, aucune variable CSS.
L'animation cubeFlip (1,2 s, ease-in-out, infinite) découpe le cycle en deux phases égales de 0,6 s. Phase 1 (0 % → 50 %) : rotateX passe de 0° à −180° — le carré bascule vers l'avant, son bord supérieur vient vers le spectateur. Phase 2 (50 % → 100 %) : rotateX reste à −180°, rotateY passe de 0° à −180° — l'élément déjà retourné pivote sur l'axe vertical. La valeur perspective(120px) est inscrite dans la propriété transform de chaque image-clé, pas sur un parent : chaque instance a son propre point de fuite indépendant. Sur un élément de 40 px, le rapport perspective/taille est de 3:1 — net sans être caricatural.
Sans backface-visibility: hidden ni transform-style: preserve-3d, le dos de l'élément est visible à 180° — c'est le même dégradé retourné horizontalement (le coin indigo passe du haut-gauche au haut-droit). Mesuré dans Chromium : au passage par l'axe (~77° de rotation autour de X), la hauteur rendue de l'élément de 40 px tombe à 9 px et la largeur monte à 48 px sous l'effet du grossissement du bord proche par la perspective.
Accessibilité
- prefers-reduced-motion absent du code : l'animation
cubeFliptourne en continu quelles que soient les préférences du système — mesuré :animationPlayState: runningsousprefers-reduced-motion: reduce. À ajouter :@media (prefers-reduced-motion: reduce) { .loader-cube { animation: none; } }. - Le cube est purement visuel : pas de
role, pas de texte, pas de régionaria-live. En tant qu'indicateur de chargement, il doit être accompagné d'un texte masqué visuellement portantrole="status"ouaria-live="polite"(exemple :<span class="sr-only" role="status">Chargement en cours…</span>). Posezaria-hidden="true"sur.loader-cubepour que les lecteurs d'écran ne remontent pas l'élément décoratif. - Contraste : le dégradé indigo (#6366f1) sur blanc ne passe pas 3:1 (≈ 2,6:1) — seuil des composants non textuels. Sur le fond sombre du code (
#0a0a0f), il atteint 4,7:1. Sur une page claire, foncez les teintes (par exemple#4338ca → #7c3aed). - L'élément de 40 × 40 px n'est pas interactif. S'il est inséré dans un bouton, c'est le
<button>qui porte le focus et l'étiquette ARIA — le cube reçoitaria-hidden="true".
Compatibilité navigateur
Requiert @keyframes, animation, transform: perspective() rotateX() rotateY() et linear-gradient. Aucune bibliothèque, aucune variable CSS, zéro JavaScript.
Sans rotateX/rotateY, le carré reste immobile en indigo. Sans @keyframes, même résultat — un carré statique visible.
Le code
Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :
<div class="loader-cube"></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 |
|---|---|---|
Taille (CSS — .loader-cube) |
40 × 40 px | Hauteur et largeur en px ou em. La perspective est en pixels absolus (120px) : si vous agrandissez fortement l'élément, augmentez-la en proportion pour conserver le même rapport de foreshortening. |
Couleur de fond (CSS — background) |
linear-gradient(135deg, #6366f1, #8b5cf6) | Dégradé ou couleur unie. La face arrière montre le même dégradé retourné horizontalement ; une couleur unie efface cet effet miroir. |
Durée (CSS — animation: 1.2s …) |
1,2 s | Durée d'un cycle complet (deux culbutes). 0.8s = rythme pressé ; 2s = retournement lent et délibéré. |
Progression (CSS — ease-in-out) |
ease-in-out | Courbe appliquée aux deux phases indépendamment. linear donne une vitesse de rotation constante ; ease-in-out produit une accélération au centre de chaque demi-tour et un bref repos en face pleine. |
Perspective (CSS — perspective(120px) dans chaque image-clé) |
120 px (rapport 3:1 sur l'élément de 40 px) | Distance d'observation simulée. 80px (2:1) = effet 3D très prononcé ; 200px (5:1) = rotation quasi isométrique, peu de foreshortening. Modifiez la valeur dans les trois images-clés (0 %, 50 %, 100 %) simultanément. |
Dos visible (à ajouter — backface-visibility: hidden) |
dos visible (comportement CSS par défaut) | Sans cette règle, la face arrière — le dégradé retourné — est visible à 180°. Avec backface-visibility: hidden, l'élément disparaît au passage par l'axe, créant un blanc net entre les deux orientations. |
| Réduction du mouvement (à ajouter) | absent du code vendu | @media (prefers-reduced-motion: reduce) { .loader-cube { animation: none; } } immobilise le cube. Alternative : passer la durée à 4s pour un mouvement très lent plutôt que de tout couper. |
FAQ
transform-style: preserve-3d ni enfants. L'illusion 3D vient de perspective(120px) rotateX() rotateY() appliqués à un élément plat : quand il bascule, la perspective déforme sa projection et le comprime jusqu'à 9 px de hauteur au passage par l'axe. Le dos n'est pas une face distincte — c'est le même dégradé retourné.scale 1 → 0 → 1) avec des délais décalés — une grille qui s'agite. Cube Flip est un seul élément qui effectue une rotation 3D réelle en deux phases sur deux axes. Les techniques n'ont rien en commun : Cube Grid n'utilise pas perspective ni rotateX/rotateY, et Cube Flip n'a pas de grille ni de décalage temporel. À noter : le CSS vendu avec Cube Flip contient par erreur le code complet de Cube Grid (@keyframes cubeGridScale et les 11 règles .loader-cube-grid) — il peut être supprimé sans effet sur Cube Flip.perspective posée sur un parent crée un espace 3D partagé pour tous ses enfants — le point de fuite est unique, centré sur le parent. La fonction perspective() dans le transform crée un espace 3D propre à chaque élément, centré sur lui-même. Conséquence ici : deux instances de .loader-cube côte à côte ont chacune leur propre point de fuite et s'animent indépendamment, sans que la perspective de l'un ne déforme l'autre.